好的, 我可以为你提供一个使用 Rust 实现 GoDaddy 动态 DNS 更新的示例程序。这个程序将包含以下功能:
- 从配置文件读取自定义变量
- 定期检查公网 IP 地址
- 如果 IP 发生变化, 调用 GoDaddy API 更新 DNS 记录
- 记录日志
首先, 我们需要一些依赖 crate:
[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
config = "0.11"
log = "0.4"
env_logger = "0.9"然后, 这里是主程序代码:
use config::Config;
use log::{error, info};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use tokio::time;
#[derive(Debug, Deserialize)]
struct Settings {
domain: String,
record: String,
api_key: String,
api_secret: String,
check_interval: u64,
}
#[derive(Serialize, Deserialize)]
struct DNSRecord {
data: String,
ttl: u32,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let settings = Config::builder()
.add_source(config::File::with_name("config"))
.build()?
.try_deserialize::<Settings>()?;
let client = Client::new();
let mut last_ip = String::new();
loop {
match get_public_ip(&client).await {
Ok(current_ip) => {
if current_ip != last_ip {
info!("IP changed from {} to {}", last_ip, current_ip);
match update_dns(&client, &settings, ¤t_ip).await {
Ok(_) => {
info!("DNS updated successfully");
last_ip = current_ip;
}
Err(e) => error!("Failed to update DNS: {}", e),
}
}
}
Err(e) => error!("Failed to get public IP: {}", e),
}
time::sleep(Duration::from_secs(settings.check_interval)).await;
}
}
async fn get_public_ip(client: &Client) -> Result<String, reqwest::Error> {
Ok(client
.get("https://api.ipify.org")
.send()
.await?
.text()
.await?)
}
async fn update_dns(
client: &Client,
settings: &Settings,
ip: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let url = format!(
"https://api.godaddy.com/v1/domains/{}/records/A/{}",
settings.domain, settings.record
);
let record = DNSRecord {
data: ip.to_string(),
ttl: 600,
};
client
.put(&url)
.header("Authorization", format!("sso-key {}:{}", settings.api_key, settings.api_secret))
.json(&vec![record])
.send()
.await?
.error_for_status()?;
Ok(())
}这个程序需要一个名为 config.toml 的配置文件, 格式如下:
domain = "yourdomain.com"
record = "@"
api_key = "your_api_key"
api_secret = "your_api_secret"
check_interval = 300要运行这个程序, 你