オフィス内に動的IPサーバー設置のアクセス事情 (自分のIPを定期通知する)

タイトル名をつけるのに悩みましたが、ちょっとした実験サーバーをオフィス内に置きたいときどうアクセスをさせるか悩みましたので忘備録です。
まあ楽にやるのであれば、インタネットプロバイダーからグローバル固定IPをもらってそれを使いDNSに登録で完了！なんですが、プロバイダーによっては固定IPを提供していなかったり、提供していても結構高額でそこまでやることもないななんてときにどうしてもインターネットからのアクセスに制限がかかるわけです。
動的IPは基本的にDHCPサーバーと呼ばれるところからIPを割り振ってもらうのですが、一定期間を過ぎたり再起動をしたときにIPが変わってしまいインターネットからオフィス内に置いたサーバーにアクセスができなくなったりするわけです。
解決方法としてはパターン別にいくつかあるのですが

- インターネットからのアクセスしてくる台数が少数の場合
*　DDNS（動的DNS）: 今回初めて利用を検討したのですがまあ要は普通のDNSに対してレコードを定期的に更新してあげる仕組みと理解しました。
*　自分の接続元IPを定期的にそれら少数の人やシステムに教えてあげてHOSTファイルかなんかに書き込んでもらう。あるいは直接IPでアクセスしてもらう。  

- インターネットの公開するサーバーもしくはアクセスするユーザーが多い場合
* DDNS（動的DNS）しかないかな...　IPでアクセスさせるのであれば場合によってはIPだけを共有するだけでもいいかも。

という感じです。いずれの場合も絶対に必要となるのが、**インターネットからアクセスできるIP**を**定期的**に通知するという機能です.
回り駆動言い方ですが、事務所のネットワークにはいくつかパターンがあるようです。

**[パターン1]** 
モデムのような機器の提供を受け自身で用意した機器にグローバルIPを設定する。
このような設定は経験的な感覚で結構少数なのではないかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955606/fac080c0-6655-9862-4bcd-676218117b06.png)

**[パターン2]**
ルータを受け取り設置（通常WIFIルータでファイヤー機能付きのが多いようです）
家庭用や比較的小規模の事務所ではこのパターンが大半なのではないでしょうか？（すみません、ビジネス向けのサービスに関しては感覚的な少数の標本でコメントしているので確証があるわけではないです）
**注意:**　このパターンの場合、インターネットからオフィス内サーバーにアクセスさせるにはNAT（Network Address Translation）という仕組みも必要です。つまりインタネットに例えば現時点で216.10.10.6/29の動的グローバルアドレスが割り当てられたとしてそれはルータに割り当てられます。通常はインタネットからオフィス内サーバーに割り振られた192.168.1.30 にはアクセスできません。それを通すためにルータにはNATの機能は必須になります。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955606/43c0febf-2c20-7a79-d004-12e6fea52c26.png)

さてここからが本題なのです。自分にアクセスするためのＩＰをどうＤＤＮＳとかに伝達ということになります。上記の例では216.10.10.x/29 でこれは一定間隔で動的に変化します。
マニュアルでやるには簡単な方法として　
https://whatismyipaddress.com/ja/index　
みたいなところにアクセスすれば自分がどのIPから来ていることを教えてくれます。これは上記のどのネットワークの構成であっても、必ずオフィス内のサーバーの入り口へのIPアドレスを教えてくれます。
パターン１でいえばサーバー自身ですし、パターン２でいえばルータのグローバルアドレスです。

上記の例でいうとその時点で割り当てられた216.10.10.x　ですね。
でもここは１時間ごと、１０分毎ましてや１分毎に毎回更新なんてマニュアルでは当然できないですし自動でやりたいところです。
自動化するのにお勧めのIPを教えてくれるサービスは
https://api.ipify.org/?format=json
です。余計なWEBレイアウト無に欲しい情報だけをJSONで教えてくれます。

例えばパターン２で設定されたプライベートアドレスもDHCPで動的に変わるマシンがあるとします。
192.168.19.100 が割り当てられてますがこれ自体もルータの再起動で変わりますし、またグローバルのほうも変わります。
```
$ ifconfig
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.15  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::250:56ff:fe81:da73  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:81:da:73  txqueuelen 1000  (Ethernet)
        RX packets 17377356  bytes 67444868249 (67.4 GB)
        RX errors 0  dropped 614  overruns 0  frame 0
        TX packets 8875758  bytes 4979725327 (4.9 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 7636  bytes 1197503 (1.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7636  bytes 1197503 (1.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

そこで以下のようなコードでインターネット上のユーザーが自分へのアクセスに必要な情報を把握します。
```
import requests
def get_global_ip():
    """
    グローバルIPアドレスを取得する。
    Returns:
        str: グローバルIPアドレス
    """
    try:
        response = requests.get("https://api.ipify.org?format=json")
        response.raise_for_status()
        return response.json().get("ip")
    except requests.RequestException as e:
        print(f"エラーが発生しました: {e}")
        return None

if __name__ == "__main__":
    global_ip = get_global_ip()
    if global_ip:
        print(f"グローバルIPアドレス: {global_ip}")
    else:
        print("グローバルIPアドレスを取得できませんでした。")
```
実行します.
```
# python iptest.py
グローバルIPアドレス: 216.10.10.5
```

今回は動的DNS（DDNS）の定期更新もとに適切な動的グローバルIPアドレスを通知するコードを忘備録として記事にしました。
この後、パターン１になるか、パターン２になるかわからないですがRoute 53でのDNSの設定と上記のコードを多少修正して利用して自動でAレコードを更新するような記事を書きたいと思います。

この通知機能を使って動的DNS（DDNS）の更新（AWS　ROUTE 53）を記事にまとめてます。
https://qiita.com/takeofuture/items/48a234fca07ebc6164f4