たけまるの日記

たけまるの日記です。web関係の技術ネタが多いですが、好きなことを適当に書いています。

フレッツのIPoEとか固定IPとかポート開放とかごちゃっとしてたのでまとめた

フレッツを使ってネット接続をする場合、PPPoEでセッションを張るというのがもう20年以上にわたり常識化されていたわけですが、ここ数年IPoE方式というのが台頭してきました。 ふわっとはわかっていて、なんとなく使ってる部分はあったのだけど、今回いろいろあってがっつりやる羽目に。 おそらく2000年代からインターネットやネットワークやってる人の常識とはかなり変わっているので、アップデートできていない人は注意(ワイや)。 一応(ギリギリ)ネットワークエンジニアの端くれとして新たに理解した部分があったのでまとめます。

世界はIPv6化にむけて大きく動いている

日本は取り残され気味、とはいえ前進している

IPv6とは何かみたいな話はwikiみてください。私も見返しました。
https://ja.wikipedia.org/wiki/IPv6

少なくとも日本において、IPv4を使わないという選択肢は、現状は無いです。 IPv4が日本のインターネットの根幹であり、IPv6はサブの位置づけ。 そうすると、(通信屋ではない)サービス事業者はIPv6にわざわざ対応する必然性は薄く、IPv4のみ提供すればビジネス上問題にはなりません。

事実、https://www.yahoo.co.jp/IPv6対応してません。

しかし、https://google.com/をはじめ、youtubefacebookなどはIPv6対応しています。 これは何故か。国別のIPv6普及率を見てみましょう。

IPv6を取り巻く状況
https://www.nic.ad.jp/ja/topics/2023/20230209-IPv6Summit-JPNICkawabata.pdf

このあたりの資料を見るに、まあ私の偏見も込ですが、インターネット先進国IPv6後進国になってます。 インドやバングラディッシュのように、人口が多く経済発展途上の国はIPv6の普及率が高いです。これはIPv4アドレスが先進国にとられ、後からインターネットが普及した途上国は、人口に足りる分のIPv4アドレスが入手できないからという事情からくるものと思われます。 対して先進国は既得権益的にIPv4アドレスを保有しているし、各種設備もv4を前提に出来上がってしまっているため、今更変更できない状態です。

そのため、世界を相手に商売をしたいサービスはIPv6対応が必須となっているわけです。

とはいえ日国内でも何もしていないわけではなく、スマートフォンにドコモやau等のSIMを使って接続しているインターネットは、無意識のうちにIPv4/IPv6のデュアルスタックになっていることがほとんどです。 またフレッツ光ネクストIPv6にネイティブ対応しているので、ネットワークに詳しくない一般のご家庭でも普通にIPv6がつながる状況に既になっている割合が多いです。

対して法人の社内ネットワークは未だにIPv4のみで構成されていることが多いのではないかと思われます。

(前提)NTT法

なんでPPPoEやIPoEという概念が生まれたか

通信を商売にしている会社はNTTやKDDIなど複数ありますが、NTTはもともと国営企業で後に民営化された会社です。 民営化されたとは言え元国営企業と民間企業が真っ向勝負するのは体力的に不公平なので、NTT法でNTTができる商売が制限されています。 それにより、フレッツは回線とプロバイダをセットで売ることができず、NTTは回線(光ファイバー)だけを売り、プロバイダ部分は別の会社を選べるようにする必要があります。 こういった政治的理由により、技術的にいろいろ不自然な状況が発生したというのがフレッツの仕組みが複雑化している要員です。 そのため、従来はPPPoEによってフレッツ回線の先につながるプロバイダを制御していたわけです。 現代のIPoEについては、フレッツ回線とプロバイダが紐づけられていて、直接契約プロバイダのIPv6アドレスを付与する事で制御しています。(後述)

対して、KDDIauひかり)は光ファイバーとインターネット接続を一緒にに売ることができるので、同じような問題は発生しないわけです。

PPPoE接続の仕組み

前段にも書いた通り、従来はフレッツの先のプロバイダにPPPoEで接続するという方式を取っていました。 そのためプロバイダのID/PWをルーターに設定した覚えのある方も多いでしょう。 これはつまりどうなっているかというと、フレッツ網とプロバイダの間にそこを取り持つ機器、網終端装置というものがあり、(感覚的に言うと)ここがPPPoEの認証をしています。 この網終端装置をプロバイダごとに設置しているわけです。 そうすると何が起こるかというと、この網終端装置がめちゃくちゃ混み合うことでネット接続が遅くなります。 また厄介なことに、この網終端装置はプロバイダの意志で簡単に増強できないという時代や、その後自由に増強できるようになっても費用負担が大きいことでプロバイダが増強したがらないという事情がありました。 これがつまり、PPPoEが遅いと言われるようになった所以です。

IPv4 PPPoE:網終端装置を自由に増設できる接続メニューの提供 https://www.geekpage.jp/blog/?id=2017-10-30-1

IPoEってなんじゃ

さて、光ファイバーのフレッツもBフレッツ(現在は申込み終了、順次NGNへ移行中)から、フレッツ光NEXT(NGN)へと移り変わります。 なかなかNGNが何かというのが一般向けには広報されてないのでわかりにくいですが、NGNは技術的にはIPv6で構成された巨大なネットワークです。 なので誤解を恐れずいうと、IPv6しか流せません。IPv4接続は、IPv6ネットワーク上を加工して無理やりIPv4パケットを流すことで実現しているので、ネイティブには純然たるIPv6回線です。

従来のPPPoEは加入者のルーターと、網終端装置の間に仮想的なトンネルを作ってパケットを流していました。 IPoEはネイティブ方式とも言われ、NGNの中を直接IPv6パケットがルーティングされる仕組みです。 そのためIPoE(かつフレッツv6オプション契約の場合、後述)でNGNに接続すると、まずIPv6アドレスが加入者ルーターに割り当てられ、そのアドレスで通信をする事になるのです。 (PPPoEはPPPoEセッションが成立してはじめてIPアドレスが割り当てられる。)

IPoE方式とVNEの役割
https://ipoe-c.jp/__assets__/pdf/ipoe_vne.pdf

フレッツv6オプションって何や

ここの理解がフレッツNGN(IPoE)の理解のキモ

あまり技術面で広報されていないので、「フレッツv6オプション」がいまいちわかりませんでしたが、私の理解では次の通りです。 まず、NGNでフレッツv6オプションを契約していない場合、「PPPoE専用回線」となります。 これで従来のBフレッツと同じ仕組みになります。

「フレッツv6オプション」を契約すると、先の通り回線にIPv6アドレスが割り当てられます。 ただこの割り当てられるアドレスには2種類あります。

「フレッツv6オプション」かつ「プロバイダとのIPoE契約が無い」場合 この場合、割り当てられるアドレスはNTTの保有する、閉域網のIPv6アドレスが割り当てられます。 先に説明したNTT法により、NTTはグローバルルーティング(要はプロバイダ)を提供できません。 その場合この用途としては、プロバイダに契約せずとも(インターネットを経由しなくても)NGN契約者同士が直接IPv6で通信する事にあります。 本社と支社の2拠点をVPNで繋ぐような用途の場合、これだけでも利用価値はあると思います。

ただし、前述の通り割り当てられるアドレスは閉域網のIPv6アドレスです。 そしてこれがいろいろな問題を引き起こす種なのです。 なぜかというと、ここで配布されるIPv6アドレスは、IPv6の規格でいう所のユニキャストアドレス(IPv4でいうグローバルIPアドレス)なのです。 理由としては、フレッツ網が巨大なために、ローカルアドレスとして使って良いIP範囲では個数が足りず、ユニキャストアドレスの範囲で設計するしかなかったとのこと。 そのため、通常の接続機器からすると「グローバルルーティングのあるはずのアドレスが割り当てられている」と認識するのですが、実際はネットに繋がらず、NGNようわからん!という話に繋がります。

それに寄って起きる問題の1つとして「NTT IPv6閉域網フォールバック問題」がありますが、ここではこれ以上追求しません。
https://www.geekpage.jp/blog/?id=2012/3/28/1

「フレッツv6オプション」かつ「プロバイダとのIPoE契約がある」場合 この場合、割り当てられるアドレスはプロバイダのIPv6アドレスになります。 これで直接プロバイダにルーティングされ(内部的にはPBRでルーティングされるとの事)、インターネットへ接続できます。 これで一番自然なインターネット接続が実現されました。(ただしIPv6のみ)

フレッツにおけるIPv6 prefix

/64? /56?

IPv6は128bitで表す広大なアドレス領域がありますが、 IPv4アドレスと違い、下位64bitはインターフェイス識別子(つまりホストアドレス)と決まっています。 IPv4であればネットワークアドレスとホストアドレスの仕切りをサブネットマスクにより自由に設定できましたが、IPv6ではできません。 CIDR表記でいくと、/64より大きな表記(/65とか/96とか)は存在しえない事になります。 つまり上位64bitでネットワークを特定する必要があります。

さて、NGNではIPv6アドレスを付与されるときに、/64または/56のprefixとして配布されます。 ここで何が起きるかというと、/64を配布された場合、2つ以上のネットワーク(セグメント)をローカル側で持てない事になります。 一般家庭(除く逸般の誤家庭)であれば特に問題になりませんが、企業ネットワークの場合これだとネットワーク分割ができなくなり困ってしまいます。

この違いは何で起こるかというと、フレッツ光NEXTの場合、ひかり電話の契約の有無で決まります。 ひかり電話を契約すると/56でprefixが付与されます。 ひかり電話契約がない場合は/64 prefixとなります。 IPv6ネットワークをこれから構築する場合、このあたりも考慮が必要ですね。

尚、10G接続であるフレッツ光クロスの場合、ひかり電話契約の有無に関わらず/56 prefixの付与となるようです。

DS-LiteとかMAP-Eとか

IPv6専用回線のNGNに、IPv4を無理やり通そうとする人々

何度も言ってきた通り、NGNIPv6専用回線です。 とはいえ日本のインターネットはIPv4なくして成り立たないのが現状で、どうしてもIPv4を使う必要があります。

ここで取りうる方法は2つです。

  1. IPv6はIPoEで使うが、IPv4はPPPoEで接続する方法
  2. IPv6はIPoEで接続し、IPv4IPv4 over IPv6技術を使って接続する方法
1. IPv6はIPoEで使うが、IPv4はPPPoEで接続する方法

こちらは特に説明する必要がないとは思いますが、後述の理由によりIPoE(IPv4)ではサーバー公開のハードルが高いです。PPPoE接続であればIPv4アドレスを最低1個は占有できる事が多いため、サーバー公開の必要がある場合はこの方法を使うことは今後もあると思われます。(マイクラサーバー立てたりね)

2. IPv6はIPoEで接続し、IPv4IPv4 over IPv6技術により接続する方法

本題はこちらです。 IPv6回線上に、無理やり加工してIPv4パケットを流す方法がとられ、これもIPoE方式といったりするのでややこしいです。 具体的にはIPv6上にトンネルを作り、IPv4パケットをカプセル化して流します。 また、カプセル化して流したIPv6パケットからIPv4パケットを取り出し、IPv4ネットワークに流すための機構が必要で、これはプロバイダ(VNE)が行います。 具体的にはDS-Lite、またはMAP-Eというプロトコルが使われます。 どちらのプロトコルを使うかは基本的にプロバイダがどちらの方式を採用してるか次第です。

まずDS-Liteについてです。 DSはDual Stackの意味だそうです。 Liteというのは何がLiteかというと、加入者側ルーターの処理が比較的軽くて済むという事のようです。 そのかわり、VNE側ではカプセル化したパケットを復号化し、キャリアグレードNAT(CGNAT)を処理する必要があるため、重めな処理になります。 このCGNATは1つのグローバルIPv4アドレスを複数加入者で共有することになり、つまり従来のPPPoE接続のルーターの内側にいるホストと同じような状況です。 いわゆるポート開放のような概念はありませんので、サーバー公開はできません。 具体的なサービス名としては、transix等が該当します。

次にMAP-Eについてです。 目的や概念としてはDS-Liteと似たようなものですが、NATの処理を加入者側ルーターで処理するのが特徴です。 このため、VNE側で大規模なCGNATを運用する必要がなく、VNE側の処理は比較的軽めとなります。 とはいえ1つのグローバルIPv4アドレスを複数加入者で共有していることには変わりなく、どのポートを自分が使えるかといった割り当ても機械的にされるため、こちらも自由なサーバー公開などはできません。 たまたま割り当てられたポートを使ってサーバー公開はできますが、現実的ではありません。 具体的なサービス名としては、v6プラス、OCNバーチャルコネクト等が該当します。 プロトコルレベルの動きは、最後に参考として紹介しています「徹底解説v6プラス」に詳しい解説があります。

固定IPの意味

PPPoE時代とは意味が違う、IPoE(IPv4)でサーバー公開するなら固定IP必須

これまで説明したきたように、IPoEによるIPv4接続においては、基本的にサーバー公開はできません。 PPPoE時代であれば、グローバルIPを最低1つは占有でき、全ポートが自由に使えたため、たまにIPアドレスが変わることを許容すればサーバー公開は自由にできました。 またIPアドレスの変化をDNSで補うDDNSというサービスもあるわけなので動的IPのデメリットはそこまで多くなく、法人で出口IPをを固定する必要があったり、VPN運用などでどうしても必要な人が固定IPサービスを契約する程度だったかと思います。

しかしIPoEによるIPv4接続においては、原理的にサーバー公開をできない仕組みになっているのは前述のとおりです。 では全く方法が無いかというと、固定IPサービスを契約すると、IPv4アドレスを1つ占有できるために全ポートが自由に使え、サーバー公開もできます。 ここがPPPoE時代でいう固定IPと、IPoE(IPv4)時代における固定IPの意味の違うところです。

クラウドVPSなど普及していますので今更自宅サーバーを立てたいという需要は減っていると思いますが、どうしても必要であれば固定IPサービスを契約してみてください。 ちなみに技術的には、IPoE(IPv4)で固定IPを通す場合、DS-LiteやMAP-Eではなく、IPIPトンネルを使うようです。

ただ残念ながら、IPoEでの固定IPサービスは法人向けで高額なものが多いです。

私は未契約ですが、IPoE(IPv4)で固定IPを比較的安く契約できるサービスとしてenひかりが良いようです。
https://enhikari.jp/koteiip.html

つまりマイクラサーバーを立てたいなら

  1. PPPoE接続にする
  2. IPoE(IPv4)なら固定IP契約をする
  3. クラウド上にサーバー構築する

のどれかって事。

まとめ

まとめるとかいいつつ長々書きましたが、フレッツでIPv6ネットワークを新規に考えるときに必要な知識がある程度入ったと思います。 散々避けてきたIPv6ですが、これで向き合う気になれました。 良きIPv6ライフを送りましょう!!

Windows11でRDP接続をすると切れる(WiFI EAP認証のケース)

Windows11のWindowsUpdateが走ったあとから、リモートデスクトップで接続できなくなる現象が発生しました。 挙動を見ていると、どうもRDPログインすると一度ネットワーク接続が切れる現象が起きている模様。 なんだこれと思って色々みていると、現象が発生している環境はWi-FiEAP認証(エンタープライズ認証)であり、この認証情報はWindowsのOSではなくユーザーと紐づいているので、ユーザーのログイン状況が変化すると切れるという事らしい。

これは、WiFiのネットワークデバイスの設定の802.1Xの設定で「資格情報の保存」をすると解消できました。 (一度保存すると「資格情報の置換」の表示になる) これでWiFi-EAP認証のユーザー情報を、OSのユーザーではなくてOS自体に紐づける操作だと解釈しました。

資格情報の保存
しかし今まではこの環境で問題なくRDPできていたのに、なんで急にできなくなったんだろう。。 WindowsUpdateで急に挙動変わるのやめてほしいですね。

eSIM設定してるiPhone11を修理したら再設定に2200円かかった話

iPhone11を使っています。 iPhoneXから11に機種変したときの1つの楽しみが、eSIMが使える事でした。 eSIMは、一般的に使われている物理的なSIMカードを使うこと無く、電子的にSIMと同じ機能を果たす仕組みです。(多分)

1つの端末で2契約を使えるという事で、1回線は通常のキャリアSIMを電話用に、1回線はパケット通信用に格安MVMOを、というような事ができます。

昔から中華製端末などではできたようですが、1台のスマホに2つSIMが入るというのを初体験したくてウズウズしてました。 日本でeSIMを自由に使えるのはIIJのみですので、これを普通に契約して使っていました。

f:id:takemaru123:20200123231421j:plain

順調にそのような運用をしていたのですが、先日うっかりiPhone11の画面を割ってしまい、AppleStore持ち込みで修理しました。 当初は画面のみの交換でデータはそのままという話だったのですが、やはり交換してみたところ不具合が見つかって全交換となりました。

最初から全交換を見込んでいたので各種データのバックアップやモバイルSuicaの移行などは恙無く完了しました。

さて悲劇はここから。 eSIMを機種変更するのは初めてでした。

結論から言うと、機種変更するのはIIJにeSIM再発行手数料として2200円払う必要があります。 電話番号も変わります。(eSIMはデータ通信しかできないので事実上問題無いですが。)

https://help.iijmio.jp/s/article/000002406 f:id:takemaru123:20200123231319p:plain

しょうがないので指示通り再発行の手続きをしました。 Webの画面から簡単にでき、操作完了から5分後くらいにeSIM登録用のアクティベーションコードがメールで送られてきました。

f:id:takemaru123:20200123232135p:plain f:id:takemaru123:20200123231521j:plain

それを設定しようやく元通り。 めでたしめでたし。

eSIM面白いなと思って飛びついたのですが、今回のように修理のようなケースのみならず、単純に機種変更の場合でもeSIM再発行手数料がかかってしまうというのは覚えておかねばならないと思いました。

AWS LambdaでPHP動かしてみた

やること

何を書こうか頭を捻っていたのですが、ちょうど良くネタが降ってきたので便乗してみます。

re:Invent 2019 で発表された製品・機能一覧 | AWS

昨今サーバーレスアーキテクチャという言葉を聞くようになりました。 従来は何らかのサービスを提供するためには、いつでもリクエストを処理できるようサーバーを常時起動させておく必要がありました。 サーバーレスアーキテクチャではリクエストが発生してからコンピュータリソースが割り当てられるため、用意していたリソースが使われずに無駄になるという事がなくなる、といった仕組みです。 たとえばVPSを1台借りていれば月額いくらという料金がかかりますが、仮に1度もリクエストが無くても料金が発生します。 サーバーレスアーキテクチャであればリクエストの量に応じて課金になるため、無駄が発生しにくくなるわけです。 また、サーバーというサイズの決まった箱を用意しなくて済むので、急激なサービス拡大によってリクエスト量が増えても対応しやすい、というメリットもあります。

LambdaはAWS(AmazonWebServices)が提供する、サーバーレスアーキテクチャを実現するサービスです。 対応している言語が限られていましたが、先日ついにPHPも利用できるようになり、PHPerのワイ大歓喜といったところでございます。

今回は簡単なPHPプログラムをLambdaにデプロイし、動作を確認するところまでをやってみました。

環境

  • macos 10.13.6
  • AWSのアカウントを用意しておく

事前準備

AWS CLIのインストール

$ brew install awscli
$ aws --version
aws-cli/1.16.60 Python/3.7.1 Darwin/17.7.0 botocore/1.12.50
$ aws configure
※Credentialsの設定をする

AWS SAM CLIのインストール

$ brew tap aws/tap
$ brew install aws-sam-cli
$ sam --version
SAM CLI, version 0.8.1

S3バケット作成(パッケージをデプロイするのに使う)

$ aws s3 mb s3://takemaru-lambda-test

コンテンツの準備

基本的には

github.com

の内容そのままですw

適当なディレクトリを作成します

$ mkdir -p test-lambda-php/src/php
$ cd test-lambda-php

template.yaml ファイルを作成します

AWSTemplateFormatVersion: 2010-09-09
Description: My PHP Application
Transform: AWS::Serverless-2016-10-31
Resources:
  phpserver:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub ${AWS::StackName}-phpserver
      Description: PHP Webserver
      CodeUri: src/php
      Runtime: provided
      Handler: index.php
      MemorySize: 3008
      Timeout: 30
      Tracing: Active
      Layers:
        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:4
      Events:
        api:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY

実行するPHPプログラムを用意します

今回は超無難にphpinfo()を動かすことに

src/php/index.php

<?php
phpinfo();

こんな感じのディレクトリ構造になりました

.
├── template.yaml
└── src
    └── php
        └── index.php

次に作成した内容をパッケージ化しデプロイします

$ sam package \
    --template-file template.yaml \
    --output-template-file serverless-output.yaml \
    --s3-bucket takemaru-lambda-test

$ sam deploy \
    --template-file serverless-output.yaml \
    --stack-name testlambda2 \
    --capabilities CAPABILITY_IAM

無事済んだらAWSコンソールのAPI Gatewayダッシュボードを確認し、APIのエンドポイントURLを確認します

https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/index

アクセスしてphpinfo()の画面が出れば成功です

f:id:takemaru123:20181206000945p:plain

まとめ

本当はもう少しいろいろやりたかったのですが、環境構築に手間取り時間がなくなってしまいました。

実際動かしてわかったのですが、最初はCakePHPでも動かしてみるかと思ったのですが、mbstring等の必要なライブラリが入っておらずそのままでは動かなそうです。

このあたりが今後の課題だと思いますが、折角ですので徐々に実案件でも使えるようにしていきたいと思います!

参考

github.com

wp-kyoto.net

qiita.com

LibreOffice calcのグラフ背景画像に任意の画像を設定しようとしてクソハマったからメモ

Draw起動してそっちから画像Importしろってよ。。 Calcの設定画面を隅から隅まで探していたのにどういうこっちゃ。。

superuser.com

PHPのDOMDocument::loadHTML()がHTMLエンティティを変換してしまう件(未解決)

あえてHTMLエンティティのまま読み込んでそのまま出力してもらいたいのだけど、loadHTML()が勝手にもとに戻してしまい、これが元で意図した動作になってくれない。

この問題はこのへんでも論じられているが、解決はしていないみたいです。

stackoverflow.com

調べてみると、これの内部処理はlibxmlが行っている模様。 で、libxmlのドキュメントを読むとこの動作を制御するためのxmlSubstituteEntitiesDefault()というのが用意されているみたい。

http://xmlsoft.org/entities.htmlxmlsoft.org

でもPHPからこの関数を叩く方法が用意されていない…。 一応要望は出されているみたいだけど、2002年から放置なので対応する気はなさそう。

https://bugs.php.net/bug.php?id=15145bugs.php.net

こんなん見ても無いもんはないw

github.com

これはもうどうにもならんので他の方法を考えることにします。。

AWS EC2(CentOS)のストレージ拡張

AmazonLinuxではなくてCentOS6です。 AmazonLinuxではオンラインで拡張できるようですが、CentOSの場合は1度OSリブートする必要があります。

AWSマネージメントコンソールからELBをリサイズ

# cat /etc/redhat-release 
CentOS release 6.6 (Final)

# lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  20G  0 disk 
└─xvda1 202:1    0   8G  0 part /

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.8G  6.0G  1.5G  81% /
tmpfs           498M     0  498M   0% /dev/shm

# wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# rpm -i epel-release-6-8.noarch.rpm
# yum install dracut-modules-growroot

# dracut --force --add growroot /boot/initramfs-$(uname -r).img
# reboot

再起動後

# lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  20G  0 disk 
└─xvda1 202:1    0  20G  0 part /

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       20G  5.9G   13G  32% /
tmpfs           498M     0  498M   0% /dev/shm

再起動したら拡張が適用されてました。 resize2fsが必要だと思っていたのだけどなんでだろう…。