SaaS

NetskopeのNPA Publisherをユーザー影響を最小限にしてアップデートする

はじめに

こんにちは、セキュリティチームのむろです。

今回はNetskopeのPublisherのアップデートで少し特殊な方法を検証したのでブログで公開していきます。

注意

本手順はサポートへ個別で問い合わせした内容に基づいてはいますが、Netskopeの公式な対応手順ではない点はご了承ください。

はじめにまとめ

  • 普通の更新手順の方が作業コストは少ない、紹介する方法はユーザー影響への考慮を最優先した手順となる
    • 管理者の作業コストを優先する場合は今回の方法は向かない
  • Publisherの新旧の切り替わりはユーザー・端末(Netskope Client)側の操作次第であるため、一定の並行稼働が必要
  • APIを利用することである程度は切り替え時の作業の負荷は下げることはできる

なお、本記事内のNetskope SupportサイトのURLはNetskope Support用のアカウントが必要となる点はご了承ください。

前提知識

NPAの仕組み

NetskopeのPrivate Access(通称NPA)はPublisherと呼ばれる中継機(サーバー)を介してプライベートネットワーク内のアプリケーション(PrivateApp)にアクセスさせる機能を持ちます。

製品名としては「ZTNA Next L7」とも表現されることもあります。

Netskope One Private Access:あらゆるアプリへのゼロトラストアクセス

Publisherの冗長化

PublisherをPrivateApps設定に2台以上登録することで冗長化の構成が可能です。

一方で冗長化をされている構成であっても、通信セッションとしてリアルタイムに利用されているPublisherが何らかの理由で停止した場合は一時的な切断は発生します(再接続時には冗長化されているので復旧はする)

Publisher自体のバージョンアップ作業時も停止が発生し、一時的な切断が発生します。

通常のPublisher更新方法

Publisherの更新方法はいくつか存在します。

  • Publisherの自動更新設定

Netskope Configure Publisher Auto-Updates

  • sshへログインしてPublisherのメニューから手動で更新

Private Access – How to Upgrade the Publisher | Community

Publisherの更新時には内部アプリの再起動が実施されるため接続中のNPA接続は切断されます。

なお、場合によっては手動でPublisher内のUbuntu OS更新で再起動が必要であったり、個別の事象によって更新処理がうまく動作しないケースもあります。

Why do Publishers show a “System restart required” message?

Publisher: shim-signed package is not able to update automatically

そういった場合には更新済みのPublisherに対してトークンの再登録を行い、Publisher定義上の入れ替えを行い実質的な更新を行うような方法あります。

  • トークンの再登録でPublisher環境の入れ替え

Best Practice for Managing Publisher Recovery and Migrations

Publisherトークンの再登録はPublisherの再起動が必要なものの、Netskope管理コンソール(goskope)上のPublisher定義自体は維持されるため、Private Appsの設定内のPublisher登録の変更は必要なく、うまく動作しなくなったPublisherの復旧としても利用される手順です。

しかし、いずれの方法も先ほど記載したように一時的な切断が避けられません。

作業を行うタイミングや自動更新で設定する日時を休日や深夜帯に設定するといったように一定の対策は可能なものの、Publisherの更新を行う場合にはNPAを利用中のユーザーにはどうしても切断するタイミングが発生します。

ユーザー影響を最大限に考慮した手順を考える

そんなわけでユーザー影響を更に最小化する方法がないか模索し、1つの方法が検証で確認できたので公開します。

なお、大前提として今回紹介する方法はシステム管理者視点では他の更新方法よりも手間がかかります。

ユーザー影響よりも更新作業コストを優先する場合には向きません。

利用中のPublisherを意図的に設定から外すとどうなるのか

NPAはPrivateAppsと呼ばれるアプリ定義内に利用するPublisherを登録して設定します。

このPrivateApps定義に複数のPublisherを登録すると冗長化された状態になると言うわけです。

さて、このPrivateApps定義で利用中のPublisherを意図的に設定から外すと以下のような挙動になります。

  • Netskope管理コンソール上で更新された構成情報はおおよそ15分間隔でNetskope Client側に更新される
  • 一方で構成情報が更新されたとしても、接続中のセッションは現在利用中の旧Publisher経由の通信を切断せずに維持をする
  • 一度、ネットワークのセッションが切れて再接続する場合は新しい構成情報をもとに新しいPublisherへ接続を行う
注意

本手順はサポートへ個別で問い合わせした内容に基づいてはいますが、Netskopeの公式な対応手順ではない点はご了承ください。

今回はこの挙動を利用してユーザー影響を最小限にしてPublisherのバージョンアップを行ってみます。

検証を行った環境と内容

  • 「テストサーバー」用PrivateApps定義には既存Publisherとして「Publisher-A」、「B」が登録されている状態

上記の状態で以下のテスト用接続を開始する

  • 「ユーザー端末」からNPA接続で「テストサーバー」へSSH接続
  • 「ユーザー端末」からpspingでtcp22への疎通を繰り返し接続

更に上記の状態から以下のようにPublisherを既存から新規へ切り替えを行う

  • 「テストサーバー」用PrivateApps定義へ新規「Publisher-C」、「D」を登録を行う
  • 「テストサーバー」用PrivateApps定義から既存「Publisher-A」、「B」の登録を削除する

SSH接続自体は切り替え作業中も維持した状態で行う

Publisher切り替え時の作業

初めはテスト用のPrivateAppsなどを作成して動作確認するとより安全かと思います。

作業内の一部はAPIを利用して一括で行うこともできます。後述の「PrivateAppsの構成変更をAPIv2を利用する」も参考ください。

作業前の状態

  • 「テストサーバー」用PrivateApps定義には既存Publisherとして「Publisher-A」、「B」が登録されている状態

新PublisherをPrivateApps定義へ登録する

  • 「テストサーバー」用PrivateApps定義へ新規「Publisher-C」、「D」を登録を行う

Publisherのステータスを確認する

  • Publisherの構成が変更になると、PublisherとPrivateAppsとの到達可能性チェックが開始される
  • 到達可能性チェックに問題なければ全て緑色のチェックマークに遷移する

到達可能性チェックはPrivate Access FAQs「What services and polling interval does a Publisher use to check if a private app/service is available?」に記載のようにPrivateAppsの定義のされ方によっては以下の制限がある点はご注意ください

  • 1つのPrivateAppsに複数ポート設定されている場合はすべてのポートがチェックがされる訳ではない
  • PrivateAppsのホストがワイルドカードのFQDNまたは CIDR ブロック指定の場合は到達可能とマークされない </aside>

旧PublisherをPrivateApps定義から削除する

  • 「テストサーバー」用PrivateApps定義から既存「Publisher-A」、「B」の登録を削除する

Publisherのステータスを確認する

  • Publisherの構成が変更になると、PublisherとPrivateAppsとの到達可能性チェックが開始される
  • 到達可能性チェックに問題なければ全て緑色のチェックマークに遷移する

到達可能性チェックはPrivate Access FAQs「What services and polling interval does a Publisher use to check if a private app/service is available?」に記載のようにPrivateAppsの定義のされ方によっては以下の制限がある点はご注意ください

  • 1つのPrivateAppsに複数ポート設定されている場合はすべてのポートがチェックがされる訳ではない
  • PrivateAppsのホストがワイルドカードのFQDNまたは CIDR ブロック指定の場合は到達可能とマークされない </aside>

Publisher切り替え後の作業

数日この並行稼働状態を維持する

  • 「利用中のPublisherを意図的に設定から外すとどうなるのか」でも記載したように新規Publisherへ切り替わるのはユーザー・端末(Netskope Client)側でPrivateAppsへのセッションが開始されるタイミングとなります
  • そのため、新規Publisherへの切り替えが完了するまで数日ほど並行稼働させます

旧Publisher内のログを確認する

数日、並行稼働したことで詳細なログベースの確認が不要と判断した場合はこの作業は不要です。

  • 旧Publisherへssh接続し、「/home/ubuntu/logs/agent.txt」を確認します
    • ローテートされたログは「agent.1.txt」などのファイル名で保管されています
  • PrivateAppsへの接続や切断がされた場合に「eventlogger.cpp:25:log():0x7f4aa8」というログが記録されます
    • 接続時は”eventId”: “NEFLWCREATE“が記録される
    • 切断時は”eventId”: “NEFLWCLOSE“が記録される
[ip-172-31-29-129:2025-05-07 13:36:54.314 +00:00] [info] eventlogger.cpp:25:log():0x7f4aa8 {"clientIp": "", "destHost": "172.31.32.244", "destPort": 22, "deviceId": "aae970ba39931d29", "eventId": "NEFLWCREATE", "proto": 6, "publisherIp": "", "publisherPop": "", "publisherPort": 0, "sourceIp": "172.31.39.162", "sourcePort": 35224, "tenant": "ns-11495", "userId": "test-user@example.com"}
[ip-172-31-29-129:2025-05-07 13:37:56.934 +00:00] [info] eventlogger.cpp:25:log():0x7f4aa8 {"clientIp": "", "destHost": "172.31.32.244", "destIp": "172.31.32.244", "destPort": 22, "deviceId": "aae970ba39931d29", "eventId": "NEFLWCLOSE", "proto": 6, "publisherIp": "", "publisherPop": "", "publisherPort": 0, "rxBytes": 328368, "sourceIp": "172.31.39.162", "sourcePort": 35224, "tenant": "ns-11495", "txBytes": 449988, "userId": "test-user@example.com"}
  • ログのタイムスタンプから旧Publisherへの新規接続(”NEFLWCREATE”)が切り替え後から発生していないことを確認します
  • ログのタイムスタンプから旧Publisherからの最後の接続(”NEFLWCLOSE”)から一定の期間が経過していることを確認します

新Publisher内のログを確認する

数日、並行稼働したことで詳細なログベースの確認が不要と判断した場合はこの作業は不要です。

  • 新Publisherも同様に「/home/ubuntu/logs/agent.txt」を確認します
  • ログのタイムスタンプから新規Publisherへの新規接続が切り替え作業後から発生し始めていることを確認します

旧Publisher環境をシャットダウンする

  • 旧Publisherを経由したNPA接続がないことを確認できたら旧Publisherを停止します

仮に旧Publisher経由のNPA通信が残っている場合はこのタイミングで切断されます

検証結果

手順内の「旧PublisherをPrivateApps定義から削除する」の構成変更から約3時間後に確認した結果は以下となります。

ssh接続

  • ssh接続は構成変更後も旧Publisherから切断されずに維持されていることを確認
  • 端末側でssh接続を終了し、再度接続した際に新Publisherへの接続に切り替わることを確認

psping(TCP22)

  • pspingによる接続は毎回セッションが異なるため、構成変更が端末へ反映された約15分後から旧Publisherから新Publisherへの接続に切り替わることを確認

その他、補足など

SkopeIT Network Eventsによる確認

手順内ではPublisher内のログである「agent.txt」を確認していますが、Netskope 管理コンソールのSkopeIT > Network EventsでNPA接続開始のイベントからどのPublisherが利用されたかは簡易的に確認することも可能です。

フィルタをクエリモードに切り替えればPublisherのCN値や名前でフィルタも可能です。

フィルタのクエリモードの詳細は以下のドキュメントを参考ください。

Skope IT Queries Library

サンプルクエリ

(traffic_type in ['PrivateApp']) and (publisher_name eq Publisher名)

PrivateAppsの構成変更をAPIv2を利用する

手順内では手動でPrivateApps定義に対してPublisher設定を管理コンソール上のGUIで新旧で切り替える操作を行いましたが、PrivateAppsの数が多いと大変です。

対応策としてはNetskopeのAPIv2を利用することで一括で操作も可能です。

そして、APIv2はテナントに含まれているSwagger内で簡単に実行することもできます。

詳細は後述のスクリーンショットや以下の公式ドキュメントを参考ください。

REST API v2 Overview

利用方法の概要は以下となります。

  • 「/api/v2/infrastructure/publishers」のGETでPublisherの一覧および各Publisher ID(publisher_id)を確認
  • 「/api/v2/steering/apps/private」のGETでPrivateApps ID(app_id)を確認
  • 「/api/v2/steering/apps/private/publishers」のPATCHで追加、DELETEで削除
    • サンプルのようにPrivateApps IDやPublisher IDで複数指定が行えるので複雑な構成でなければ一括で処理が行えます
    <aside> <img src=”/icons/info-alternate_lightgray.svg” alt=”/icons/info-alternate_lightgray.svg” width=”40px” /> 初めはテスト用のPrivateAppsなどを作成して動作確認するとより安全かと思います。 </aside>

ただ、PrivateAppsの数が少ない場合は手動でやった方が楽かもしれません。

利用が終わったトークンは削除か無効化しておきましょう

個人的な所感

今回の手順はそれなりに面倒なため、個人的には2台以上で冗長化した構成にして、1台ずつトークンの再登録でPublisherを入れ替える方法をユーザーアナウンスの上で休日や夜間帯に行う方法が一番確実で楽に思いました。

Best Practice for Managing Publisher Recovery and Migrations

ただ、ユーザー影響を最小限に抑えたいユースケースにおいては今回の手順が有効だと思います!

おわりに

今回は実際にお客さんからのリクエストでユーザー影響を最大限に考慮した更新方法がないか、ということで検証したPublisherのアップデート手順をブログ化してみました。

もしも、皆さんのお役に立てば幸いです。

むろ

おいしいおつまみとお酒が好きです。
最近ハマっているのは芋焼酎のソーダ割り。

履き物の基本は下駄の人です。
好きな漫画はワールドトリガーです。