Ubuntuの動的IPアドレス環境でDDNSを使ってドメイン取得する

#はじめに
今回は[お名前.com](https://www.onamae.com/)を使ってドメイン取得をしたのでその手順を残しておきます。
またグローバルIPアドレスを固定するのはめんどくさいし、お金かかるっぽかったので動的IPアドレスの環境でやりました。

ちなみに一応これ↓の続きです。
[Ubuntu、Apacheを用いて自宅webサーバー構築](https://qiita.com/m-m-mame/items/a8ca30058e7a2a9a24f1)
ところどころ読んでいる前提で書いているのでわからないところがあったら一読していただけたらと思います。

#注意
ドメイン取得には無料でする方法もありますが、今回は独自ドメインが欲しかったので有料のほうでしています。
またお名前.comでのDDNSに関してはUbuntu環境での動作は公式の方法ではないため、この記事の内容は`自己責任`で実行してください。

#目次
1.使用環境
2.ちょこっと説明
　・ドメインってなに？
　・DDNSってなに？
　・じゃあタイトルにもあるDDNSってなに？
3.実践
　・お名前.comでドメイン取得
　・DDNS設定
4.最後に

***
#1.使用環境
###インターネット回線
ドコモ光　　(線自体はFLETS光)
ISP:plala
接続方式:IPv4 over IPv6 （OCNバーチャルコネクト使用）
グローバルIPは固定してないです
ルーター:Aterm WG1200HGHS4
ONU:PR-400KI

###バージョン
Ubuntu 20.04.14 LTS

#2.ちょこっと説明
どうてもいいからやらせろって人は読み飛ばしてもらって結構です。

##2-1.ドメインってなに？
　簡単に言うと、ネット上の住所です。ネット上の住所といえばグローバルIPアドレスのことを思い浮かべる人もいると思いますが、ドメインとはそのグローバルIPアドレスを分かりやすく覚えやすい文字列に変換したものと思ってもらって大丈夫です。
　そのため前回の記事でもやったようにURLの欄にグローバルIPアドレスを入れるのと、そのグローバルIPアドレスに対応するドメイン名を入れるのとは意味が同じになってきます。

前回の記事のURLを例として挙げると、
![新規 Microsoft PowerPoint プレゼンテーション.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/5266bebc-f722-3521-3d77-f46abe676470.jpeg)
てな感じになってます

##2-2.DDNSってなに？
 DDNS(Dynamic Domain Name System)の前にDNS（Domain Name System）の説明からします。
DNSとはドメイン名とIPアドレスを対応させるシステムのことを言います。そのためgoogle.comなどのドメイン名を入れるとgoogleのサイトが表示されるのは、裏でDNSによってgoogle.com→999.888.777.666に変換されているからです。（googleのグローバルIPアドレスを999.888.777.666とする）

　次にDDNSとは名前にダイナミックDNSとあるように、動的なIPアドレスに対応したDNSになっています。動的IPとは接続ごとに変わる可能性のあるISPから割り当てられるグローバルIPアドレスのとこを言います。
　例えば、google.comのDNSに登録したグローバルIPアドレスが999.888.777.666だとして、サーバーのIPアドレスが変わってしまって111.222.333.444になってしまった場合、google.comと入力しても登録された先のグローバルIPアドレスが存在しなくなるためアクセスすることができなくなります。（まあ企業とかはIPアドレス固定してるやろうからこんな問題は起こらんと思うけど…）
　このような場合に一定時間おきにDNSサーバーに自分の持つサーバーが、「僕のIPアドレスはこれ～」って感じで送信することによって常にドメイン名と自分のサーバーのIPアドレスを対応させることができます。


#3.実践
それでは説明も終わりにして実際に取得していきたいと思います。
##3-1.お名前.comでドメイン取得
まず以下のサイトにアクセスしてください。
https://www.onamae.com/

アクセスしたら、下の矢印の部分に自分が欲しいドメイン名を入力してください。（トップクラスドメインの値段表→https://www.onamae.com/service/d-price/）
この際、同じドメイン名は世界で1つしか存在できないため好きな名前を入れてもそれがすでに使われている場合使用することができません。特にこだわりがないならトップドメイン（.comとか.netとか）を変更して使用されてなさそうなのを探すのもありです。
![Desktop Screenshot 2022.01.14 - 04.18.14.99_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/92c84f7d-2401-a2e6-fa34-2e081ac2058b.jpeg)

次の画面で入力したドメインが既に使用されているかの確認と、実際にどのドメインを購入するか選択します。（赤矢印）
![Desktop Screenshot 2022.01.14 - 04.26.44.77_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/5cfb4556-41d5-c3b0-eac6-f72843a77bc4.jpeg)

次に具体的な契約内容を入力します。水色矢印は今回は自宅サーバーを使用するので「使用しない」。申込内容は自由にしてください。最後に緑矢印でユーザー情報を登録してください。
この後に個人情報などを入力して登録を完了してください。
![Desktop Screenshot 2022.01.14 - 04.27.40.75_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/dd3c6c63-ff21-e414-84ec-7f26878d3845.jpeg)

***
ここまでで登録自体は完了です。次にこの登録したドメイン名を自宅サーバーのグローバルIPアドレスに紐づけしていきたいと思います。
登録後、お名前.comにログインして　ドメイン設定＞DNS設定/転送設定＞設定したいドメイン名を選択して次へ＞DNSレコード設定を利用する
![Desktop Screenshot 2022.01.14 - 04.55.41.80_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/21c7e330-ced1-9257-2581-0a2dc6328a30.jpeg)
ホスト名は空白、TTLは適当に、VALUEに自分のサーバーのグローバルIPアドレスを入力して適用してください。
![Desktop Screenshot 2022.01.14 - 05.23.30.46_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/10b53cc0-e795-a3f9-d1c8-7e7da63eb0bd.jpeg)

この状況でドメイン取得自体は終わりです
この段階で
http://（いまとうろくしたドメイン名）:（ポート番号）/test.html
でアクセスすることができるようになっています（前回の記事の続き）
ちなみにv6プラスを使用していない家庭ならポート番号は不要です
![InkedIMG_7076_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2406056/9ee94e39-6707-50d1-f097-5286f29044c4.jpeg)
※同じネットワークないではグローバルIPを使用しているため開けないのでスマホで見てます

##3-2.DDNS設定
OSがwindowsなら公式がソフトを出してくれているのですがubuntuの場合はそんなものはないのでスクリプトから設定していきたいと思います。
好きなところに以下のpythonファイルを作成してください。(今回は/home/userにserverというフォルダを作ってそこに保存しました)

```
import ssl
import json
import socket
import urllib.request

def getip():
    url = "http://inet-ip.info/ip"
    req = urllib.request.Request(url)
    res = urllib.request.urlopen(req)
    ip = res.read().decode()

    return ip

def getdns(domain):
    url = "https://dns.google.com/resolve?name={domain}&type=A".format(domain=domain)
    req = urllib.request.Request(url)
    res = urllib.request.urlopen(req)
    data = json.loads(res.read().decode())
    return data["Answer"][0]["data"]

def updateip(ip):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(10)

    s = ssl.wrap_socket(sock)
    s.connect(("ddnsclient.onamae.com", 65010))

    # print(s.recv(1024).decode())

    data = """LOGIN
USERID:youruserid????
PASSWORD:yourpassword????
.
MODIP
HOSTNAME:www????
DOMNAME:example.com????
IPV4:{ip}
.
LOGOUT
.""".format(ip=ip)

    for line in data.split("\n"):
        s.send(line.encode() + b"\r\n")
        # if line == ".":
        #     print(s.recv(1024).decode())

    s.close()

if __name__ == "__main__":
    update_ip = getip()
    now_ip = getdns("example.com")
    print("before:", now_ip)
    print("after:", update_ip)

    if now_ip == update_ip:
        print("nothing to do")
    else:
        print("update ip")
    print("complete")
```

※以下のサイトから引用しました(ちょこっと変えてます)
https://blog.sky-net.pw/article/140
ここでのidなどはお名前.comのものです

あとはこのプログラムを定期的に実行するようにすれば終了です
そのためにcronというスクリプトを自動実行するデーモンプロセスを使います。

```
cd /home/user
mkdir server
```

```
cd /home/user/server
```

先ほどのpythonファイルをここに保存しておきます。
次にcronでpythonを実行させるためのshellを作っていきます。

```
nano ddns.sh
```

この中の下のほうに書き込むやつ↓

```
#!/bin/bash

python3 /home/user/server/py_ddns.py
```

shellが実行できるように権限を設定する

```
chmod 755 ddns.sh
```

最後に実際にこのスクリプトを一定時間ごとに実行するcronを設定する
今回はcron.dディレクトリに設定ファイルを作成する方法で行きます

```
sudo cp /etc/crontab /etc/cron.d/cron_ddns
```

```
sudo nano /etc/cron.d/cron_ddns
```

これに書き込むやつ↓

```
# 60分ごとに実行する
*/60 * * * *   user /bin/bash /home/user/server/ddns.sh
```

最後にcron設定を反映させるためにcronの再起動を行います。

```
sudo service cron restart
```

これでおしまいです。

#4.最後に…という名の雑談
正直グローバルIPアドレス変わるって言われてるけどめったに変わらないんで（個人差あり？）最後の工程手動でたまにやってもよさそうなレベルだと思います。
自分の自宅サーバーは特に公開するとかではなく個人用として使っていく予定なんで正直ドメイン取得する理由ないです。まあ結局は自鯖含めロマンだよね