位置情報配信プロトコルのNTRIPをNginxでリバースプロキシする方法

takahashi 著者:takahashi

位置情報配信プロトコルのNTRIPをNginxでリバースプロキシする方法

高橋です。

ご存知の方もいらっしゃるかもしれませんが、静岡大学浜松キャンパスに設置された高精度のGNSSアンテナを用いた測位情報を配信するシステム(hamamtsu-gnss.org)が整い、ついに浜松市内でRTK(リアルタイムキネマティック)ができる環境が整いました。

詳しくは
https://hamamatsu-gnss.org/
をご覧いただけましたら幸いです。

ざっくり説明するとRTKを行う際、実際に自分の位置を計測する”移動局(ローバー)”と、厳密な位置情報が既にわかっている場所に置かれた”固定局(ベース)”の2つが必要となってきます。したがって移動局は何らかの方法で固定局の情報を受信し続ける必要があるのですが、その方法として、”インターネット”経由で受信を行う方法があります。
今回開設されたhamamatsu-gnss.org局もインターネット経由で位置情報を配信するタイプの固定局で、配信プロトコルとして”NTRIP”と呼ばれるものを利用しています。

さて、そのhamamatsu-gnss.orgを開設する際に、”大学などでも受信できるように80番ポートで通信できるようにしてほしい。”という話がありました。
大学などの教育機関では、ネットワークに制限を設けているところが多く、80(http)、443(https)あたりの必要最低限のポートしか開けていないところも多くあります。
しかし、hamamatsu-gnss.orgのホームページも同様に80番ポートを使用するので、このままでは両立ができません。

最近はNode.jsやRuby on Railsなどが出回ってきて、同ホストに複数のWebサーバが立つことも少なくはなくなってきているので、今回のように一つのポートを取り合ってしまうような事態も往々にしてあります。こういう場合は”リバースプロキシ”という仕組みを用いることで一つのポートを複数のサーバープログラムで共有することができます。

今回も、まず思いついたのはこの方法だったのですが、今回共有させたいのはNTRIPという得体のしれないプロトコル。
いろいろ調べてみてもNTRIPとHTTPを同時にプロキシできるソフトやプログラムは見つけられませんでした。

どうしよかと困っていたところ、あることが判明。

http://gpspp.sakura.ne.jp/diary200703.htm
こちらのサイトで解説されているようにNTRIPはなんとHTTPベースのプロトコルでした…!(プロジェクトを共同で進めている木谷先生に教えていただきました。)

一応実験としてブラウザからNtip配信のポートに直繋ぎしてみたら、ちゃんとレスポンスが返ってきました。

telnetでも確認しましたが、ちゃんと応答が返ってきます。

しかし、NTRIPがHTTPのデータとして扱うことができるというのであれば話は早い。
上にあげたのと同様にリバースプロキシしてやれば共存させられます。

ということで早速設定。
リバースプロキシには非常に柔軟な設定ができる有能なNginxを使います。
(NginxはWebサーバーでありながらHTTP以外にもimapやpop、さらにはtcp(ドメインベースは不可)のプロキシができたりする、いい意味でかなり変態なソフトです。)

早速設定していきます。
一部省略してますが、以下のような設定にしました。

バーチャルホスト(https)

server {

  listen 443 default_server; #443番にアクセスされた時のデフォルトのバーチャルホストに設定

  ssl on;
  ssl_certificate /path/to/ssl.pem; #SSL証明書のパス
  ssl_certificate_key /path/to/sslkey.pem; #SSL証明書の秘密鍵のパス

  client_max_body_size 1g;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # クライアントの IP アドレス
  proxy_set_header X-Forwarded-Host $host; # オリジナルのホスト名クライアントが Host リクエストヘッダで渡す。
  proxy_set_header X-Forwarded-Server $host; # プロキシサーバのホスト名
  proxy_set_header X-Real-IP $remote_addr;
  location / {
    proxy_pass https://localhost:8081; #プロキシの向き先の設定(https)
  }
}

バーチャルホスト(NTRIP)

server {
    listen 80 default_server; #80番にアクセスされた時のデフォルトのバーチャルホストに設定
    server_name .ntrip.hamamatsu-gnss.org;

        client_max_body_size 1g;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection "";

     #伝送を効率化するチューニング
        keepalive_timeout 0; #キープアライブ無効化
        tcp_nodelay on; #パケットを極力まとめて送付するNagleアルゴリズムを無効化
        tcp_nopush off; #関係なさそうだが一応設定
        proxy_buffering off; #バッファリング無効化(重要)
        #効率化設定ここまで
        location / {
                proxy_pass http://localhost:2101; #プロキシの向け先をNTRIPサーバーに設定
        }
}

当環境では今後を考えてhamamatsu-gnss.org:80へのアクセスはhamamatsu-gnss.org:443へリダイレクトさせてますが、80番でWebページを待ち受けることも可能です。

回線の輻輳を防ぐためにある程度データをまとめて送付しようとする機能がNginxにありますが、ストリーミングの場合は遅延につながってしまいます。
チューニングはこの設定の無効化が主となっています。

HTTPに準拠している以上はhostヘッダーにアクセス時のホスト名を含めるルールになっているのですが、一部のNTRIPクライアントでアクセスしたときは何故か判定がうまく行かずにデフォルトのバーチャルホストへつながってしまうことがありました。
Webページの方は最近のブラウザであればデフォルトでなくても問題なくつながるので、80番ポートのデフォルトをNTRIP側に設定してあります。

これで無事NTRIPが一般配信できるようになりました。

今後、RTK-GNSS向けの位置情報の配信サービスを構築予定…という方は是非参考にしていただけましたら幸いです。

hamamatsu-gnss.orgはGPS以外にも複数の測位衛星から受信したデータを配信していて、RTK-GPSよりも高い精度で測位ができます。
全国には他には殆どない設備ですので、是非ご活用いただけましたら嬉しいです。

———————————————————-

位置情報の精度、センチ単位に 静大准教授ら研究 – @S
http://www.at-s.com/news/article/education/college/367429.html

※この記事は、以前私が書いた記事の本文を一部修正したものです
  • この記事いいね! (0)

著者について

takahashi

takahashi administrator

Webエンジニア。 趣味で自宅サーバーを稼働中。 ファンタジーが好き。