なぜこれが必要なのですか?
仕事から自宅のコンピューターにsshでアクセスする必要が非常に頻繁にあり、プロバイダーが白いが動的に変化するIPアドレスを提供することがありました。 もちろん、ダイナミックDNSを選択したため、最初に出会った無料のno-ipプロバイダーを選びました。 彼らのデーモンは、サービスから無料の第3レベルドメインのdnsレコードを変更するという素晴らしい仕事をしました。そして、CNAMEは私のドメインでそのドメインに登録されました。
これはすべて、Zyxel Keenetic Gigaを購入するまで完璧に機能しました。 彼はすぐに使えるIPアドレスのない友人ですが、何らかの理由で今はドメインにアクセスできませんでした。 この問題は、プロバイダーから静的IPを購入し、
amaraoの
優れたガイドを使用してssh構成に書き込むことで解決できますが、それも面白くありません! それで、あなたのサービスを書く時です!
実際、どこでIPアドレスを取得しますか?
私が最初に尋ねたのは、まさにこの質問でした。 無料のSTUNサーバーの1つを使用することができました(幸いなことに、goのstunクライアントはgithub上にあります)、一部のサービスを恐怖に陥れる可能性がありますが、できるだけ頻繁に自分のアドレスを確認するつもりでした。 私は自分で何でもインストールできるサーバーを持っているので、私は狂気に単純なサービスを書くことにしました。
upd:問題を解決するいくつかの方法:
IPクライアントを単に発行するサービス
youripと呼びます。 GETリクエストで/ ipにipを返すだけです。
簡単にするために
httprouterを使用することにしました。これは外出先で最速で最も簡単なルーターです。 これが最初で唯一のハンドラーです。
func PrintIp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, r.Header.Get("X-Real-IP")) }
応答でヘッダー「X-Real-IP」の値を書き込むだけです。 このヘッダーは、構成するとnginxによって渡されます。 また、リバースプロキシ経由ではなく直接このサービスにアクセスする場合は、r.Header.Get( "X-Real-IP")の代わりにr.RemoteAddrを使用する必要があります。
プログラムコード全体(githubでも
入手可能 ):
package main import ( "fmt" "github.com/julienschmidt/httprouter" "log" "net/http" "flag" )
nginxを構成するために残ります。 このようなもので十分でしょう:
upstream yourip { server locahost:888;
そして、例えば./yourip -port = 888などのサービスを開始します
このリンクをクリックすると、サービスの動作を確認できます。サービスをホストする場所がない場合は、
このリンクを使用することもできます。
Cloudflareでレコードを更新する方法は?
Cloudflare apiには、特定のドメインのエントリを変更できる
rec_editメソッドがあります。
レコード識別子を見つける
最初にレコードのIDを何らかの方法で見つける必要があります。別の方法がこれに役立ちます
-rec_load_all次のようなPOST要求を行う必要があります。
curl https://www.cloudflare.com/api_json.html \ -d 'a=rec_load_all' \ -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25' \ -d 'email=sample@example.com' \ -d 'z=example.com'
そして、あなたはそれを外出先で行う必要があります。 すばらしい
net / urlおよび
net / httpパッケージがこれを助けてくれます。
まず、ベース
URLを準備します
この関数は、コードを繰り返さないようにするのに役立ちます。 APIに対して合計2つのリクエストを行います。
次に、パラメーターを追加します。
u := Url()
理解を深めるには、「
URLタイプと
値 」を参照してください。
リクエストを作成して
実行します。
client = http.Client{} req, _ := http.NewRequest("POST", reqUrl, nil) res, err := client.Do(req)
jsonで応答を処理するには、応答を何らかの構造に逆シリアル化する必要があります。 答えの例を見て、これをコンパイルしました:
type AllResponse struct { Response struct { Records struct { Objects []struct { Id string `json:"rec_id"` Name string `json:"name"` Type string `json:"type"` Content string `json:"content"` } `json:"objs"` } `json:"recs"` } `json:"response"` }
したがって、答えを解析するときに必要なデータのみを取得します。
次に、受信したデータを処理して、すべてのレコードを調べます。
for _, v := range response.Response.Records.Objects {
最後に、必要なものを見つけました-識別子
レコードを変更する
再度リクエストを作成する必要があります。 URLの収集を始めましょう:
u := Url() values := u.Query() values.Add("email", *email) values.Add("tkn", *token) values.Add("a", "rec_edit") values.Add("z", *domain) values.Add("type", "A") values.Add("name", *target) values.Add("service_mode", "0") values.Add("content", ip) values.Add("id", strconv.Itoa(id)) values.Add("ttl", fmt.Sprint(*ttl))
これで、IPアドレスを置き換えるために必要なすべての情報が得られました。 前回と同様に、リクエストを作成して実行するだけです。
req, _ := http.NewRequest("POST", reqUrl, nil) res, err := client.Do(req)
実際、これが楽しみの終わりです。 これら2つのクエリは別々の関数に送信され、必要な変数はすべてフラグに送信され、メインの無限ループが作成されます。
func main() { flag.Parse()
それだけです コード
はgithubにあります。完全なコード package main import ( "encoding/json" "errors" "flag" "fmt" "io/ioutil" "log" "net/http" "net/url" "strconv" "time" )