diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43777a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +config.php \ No newline at end of file diff --git a/README.md b/README.md index 2afeb3d..e1f9fff 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,10 @@ Cloudflare Partner Management Panel 打开config.php,根据里面的注释进行设置后即可使用 -English version: [https://github.com/Netrvin/CFPMP/tree/en-v0.2.3](https://github.com/Netrvin/CFPMP/tree/en-v0.2.3) - ## 功能 * CNAME接入 * reCAPTCHA * 设置回源地址为IP(基于sslip.io)(默认关闭此功能) +* 通过 TXT 记录验证域名是否受用户控制 可用实例:[https://cf.yuzu.im/](https://cf.yuzu.im/) diff --git a/add_domain.php b/add_domain.php index 59a4ae1..f2608c2 100644 --- a/add_domain.php +++ b/add_domain.php @@ -3,24 +3,31 @@ $cloudflare->is_login(); -function msg($s){ - $_SESSION["msg"]=$s; +function msg($s) +{ + $_SESSION["msg"] = $s; header("Location: domains.php"); exit(0); } -if (empty($_POST["domain"])){ +if (empty($_POST["domain"])) { msg("域名不能为空"); } -$r=$cloudflare->zone_set($_POST["domain"],$_POST["domain"],"www:".$_POST["domain"]); +if (Enable_TXT_Verification){ + if (!$cloudflare->check_txt_record($_POST["domain"])){ + msg("TXT 记录验证失败"); + } +} + +$r = $cloudflare->zone_set($_POST["domain"], $_POST["domain"], "www:" . $_POST["domain"]); -if ($r["result"]=="success"){ +if ($r["result"] == "success") { msg("添加成功"); -}else{ - if (empty($r["msg")){ +} else { + if (empty($r["msg"])) { msg("请刷新本页面以确认域名是否添加成功"); - }else{ - msg("添加失败:".$r["msg"]); + } else { + msg("添加失败:" . $r["msg"]); } } diff --git a/auth.php b/auth.php index 14bee04..b9bf75d 100644 --- a/auth.php +++ b/auth.php @@ -2,36 +2,33 @@ include_once("cf.class.php"); -function msg($s){ - $_SESSION["login_msg"]=$s; +function msg($s) +{ + $_SESSION["login_msg"] = $s; header("Location: index.php"); exit(0); } -if (Enable_reCAPTCHA) -{ - if (!empty($_POST["g-recaptcha-response"])) - { - if (!($cloudflare->reCAPTCHA($_POST["g-recaptcha-response"]))) - { +if (Enable_reCAPTCHA) { + if (!empty($_POST["g-recaptcha-response"])) { + if (!($cloudflare->reCAPTCHA($_POST["g-recaptcha-response"]))) { msg("请完成验证码"); } - }else{ + } else { msg("请完成验证码"); } } -if ((!empty($_POST["email"]))&&(!empty($_POST["password"]))) -{ - $r=$cloudflare->login($_POST["email"],$_POST["password"]); - if ($r["result"]=="success") - { - $_SESSION["user_key"]=$r["response"]["user_key"]; - $_SESSION["email"]=$r["response"]["cloudflare_email"]; +if ((!empty($_POST["email"])) && (!empty($_POST["password"]))) { + $r = $cloudflare->login($_POST["email"], $_POST["password"]); + if ($r["result"] == "success") { + $_SESSION["user_key"] = $r["response"]["user_key"]; + $_SESSION["email"] = $r["response"]["cloudflare_email"]; + if (Enable_TXT_Verification) $_SESSION["txt_verification"] = password_hash(Random_String.$_SESSION["email"],PASSWORD_BCRYPT ); header("Location: domains.php"); - }else{ - msg("登录 / 注册失败:".$r["msg"]); + } else { + msg("失败:" . $r["msg"]); } -}else{ +} else { msg("用户名和密码不能为空"); } diff --git a/cf.class.php b/cf.class.php index e66dedd..ace8773 100644 --- a/cf.class.php +++ b/cf.class.php @@ -2,116 +2,129 @@ include_once("config.php"); +if (Enable_TXT_Verification&&(strlen(Random_String)<64)){ + die("Please set Random_String in config.php or disable TXT record verification"); +} + session_start(); -class CF { - public function post($data){ - $data["host_key"]=HOST_KEY; - $ch=curl_init(); - curl_setopt($ch,CURLOPT_URL,"https://api.cloudflare.com/host-gw.html"); - curl_setopt($ch,CURLOPT_POSTFIELDS,$data); - curl_setopt($ch,CURLOPT_TIMEOUT,10); - curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); - $r=curl_exec($ch); +class CF +{ + public function post($data) + { + $data["host_key"] = HOST_KEY; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "https://api.cloudflare.com/host-gw.html"); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $r = curl_exec($ch); curl_close($ch); - return json_decode($r,true); + return json_decode($r, true); } - public function login($email,$password){ - $data["act"]="user_create"; - $data["cloudflare_email"]=$email; - $data["cloudflare_pass"]=$password; - $data["unique_id"]=NULL; - return self::post($data); + public function login($email, $password) + { + $data["act"] = (Allow_Register ? "user_create" : "user_auth"); + $data["cloudflare_email"] = $email; + $data["cloudflare_pass"] = $password; + $data["unique_id"] = NULL; + return self::post($data); } - public function logout(){ - if (!empty($_SESSION["email"])){ + public function logout() + { + if (!empty($_SESSION["email"])) { unset($_SESSION["email"]); } - if (!empty($_SESSION["user_key"])){ + if (!empty($_SESSION["user_key"])) { unset($_SESSION["user_key"]); } } - public function is_login(){ - if ((empty($_SESSION["email"]))||(empty($_SESSION["user_key"]))){ + public function is_login() + { + if ((empty($_SESSION["email"])) || (empty($_SESSION["user_key"]))) { header("Location: index.php"); exit(0); } } - public function user_lookup(){ - $data["act"]="user_lookup"; - $data["cloudflare_email"]=$_SESSION["email"]; - return self::post($data); - } - - public function zone_set($zone_name,$resolve_to,$subdomains){ - $data["act"] = "zone_set"; - $data["user_key"] = $_SESSION["user_key"]; - $data["zone_name"] = $zone_name; - $data["resolve_to"] = $resolve_to; - $data["subdomains"] = $subdomains; - return self::post($data); - } - - public function zone_delete($zone_name){ - $data["act"] = "zone_delete"; - $data["user_key"] = $_SESSION["user_key"]; - $data["zone_name"] = $zone_name; - return self::post($data); - } - - public function zone_lookup($zone_name){ - $data["act"] = "zone_lookup"; - $data["user_key"] = $_SESSION["user_key"]; - $data["zone_name"] = $zone_name; - return self::post($data); - } - - public function update_record($zone_name,$record){ - if (empty($record["@"])){ - $record["@"]=$zone_name; + public function user_lookup() + { + $data["act"] = "user_lookup"; + $data["cloudflare_email"] = $_SESSION["email"]; + return self::post($data); + } + + public function zone_set($zone_name, $resolve_to, $subdomains) + { + $data["act"] = "zone_set"; + $data["user_key"] = $_SESSION["user_key"]; + $data["zone_name"] = $zone_name; + $data["resolve_to"] = $resolve_to; + $data["subdomains"] = $subdomains; + return self::post($data); + } + + public function zone_delete($zone_name) + { + $data["act"] = "zone_delete"; + $data["user_key"] = $_SESSION["user_key"]; + $data["zone_name"] = $zone_name; + return self::post($data); + } + + public function zone_lookup($zone_name) + { + $data["act"] = "zone_lookup"; + $data["user_key"] = $_SESSION["user_key"]; + $data["zone_name"] = $zone_name; + return self::post($data); + } + + public function update_record($zone_name, $record) + { + if (empty($record["@"])) { + $record["@"] = $zone_name; } - $at=$record["@"]; + $at = $record["@"]; unset($record["@"]); - if ((Enable_A_Record) && (filter_var($at,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4))){ - $at=$at.'.sslip.io'; + if ((Enable_A_Record) && (filter_var($at, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))) { + $at = $at . '.sslip.io'; } - $str=""; - foreach ($record as $key => $value){ - if ((Enable_A_Record) && (filter_var($value,FILTER_VALIDATE_IP,FILTER_FLAG_IPV4))){ - $str.=$key.":".$value.".sslip.io,"; - }else{ - $str.=$key.":".$value.","; + $str = ""; + foreach ($record as $key => $value) { + if ((Enable_A_Record) && (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))) { + $str .= $key . ":" . $value . ".sslip.io,"; + } else { + $str .= $key . ":" . $value . ","; } } - if (empty($str)){ - $str="www:".$zone_name; - }else{ - $str=substr($str,0,strlen($str)-1); + if (empty($str)) { + $str = "www:" . $zone_name; + } else { + $str = substr($str, 0, strlen($str) - 1); } - return self::zone_set($zone_name,$at,$str); + return self::zone_set($zone_name, $at, $str); } - public function remove_zone_name($zone_name,$data){ - foreach ($data["hosted_cnames"] as $record => $set) - { - if (strlen($record) > strlen($zone_name)){ - $record2 = substr($record,0,strlen($record)-strlen($zone_name)-1); - }else{ - $record2="@"; + public function remove_zone_name($zone_name, $data) + { + foreach ($data["hosted_cnames"] as $record => $set) { + if (strlen($record) > strlen($zone_name)) { + $record2 = substr($record, 0, strlen($record) - strlen($zone_name) - 1); + } else { + $record2 = "@"; } $data["hosted_cnames"][$record2] = $set; unset($data["hosted_cnames"][$record]); } - foreach ($data["forward_tos"] as $record => $set) - { - if (strlen($record) > strlen($zone_name)){ - $record2 = substr($record,0,strlen($record)-strlen($zone_name)-1); - }else{ - $record2="@"; + foreach ($data["forward_tos"] as $record => $set) { + if (strlen($record) > strlen($zone_name)) { + $record2 = substr($record, 0, strlen($record) - strlen($zone_name) - 1); + } else { + $record2 = "@"; } $data["forward_tos"][$record2] = $set; unset($data["forward_tos"][$record]); @@ -119,30 +132,38 @@ public function remove_zone_name($zone_name,$data){ return $data; } - public function reCAPTCHA($response){ - $url= "https://www.recaptcha.net/recaptcha/api/siteverify"; - $data=array ( + public function reCAPTCHA($response) + { + $url = "https://www.recaptcha.net/recaptcha/api/siteverify"; + $data = array( "secret" => reCAPTCHA_Secret, "response" => $response ); - $ch=curl_init(); - curl_setopt($ch,CURLOPT_URL,$url); - curl_setopt($ch,CURLOPT_POSTFIELDS,$data); - curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); - curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10); - $r=curl_exec($ch); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + $r = curl_exec($ch); curl_close($ch); - $re=json_decode($r,true); - if (!empty($re["success"])){ - if ($re["success"]=="true"){ + $re = json_decode($r, true); + if (!empty($re["success"])) { + if ($re["success"] == "true") { return true; - }else{ + } else { return false; } - }else{ + } else { return false; } - } + } + + public function check_txt_record($domain){ + foreach(dns_get_record("cfpmp.".$domain, DNS_TXT) as $v){ + if (password_verify(Random_String.$_SESSION["email"], $v["txt"])) return true; + } + return false; + } } -$cloudflare=new CF(); \ No newline at end of file +$cloudflare = new CF(); \ No newline at end of file diff --git a/config.php b/config.php index a1bccde..2b96f32 100644 --- a/config.php +++ b/config.php @@ -1,15 +1,22 @@ is_login(); -function msg($s){ - $_SESSION["msg"]=$s; +function msg($s) +{ + $_SESSION["msg"] = $s; header("Location: domains.php"); exit(0); } -if (empty($_POST["domain"])){ +if (empty($_POST["domain"])) { msg("域名不能为空"); } -$r=$cloudflare->zone_delete($_POST["domain"]); +$r = $cloudflare->zone_delete($_POST["domain"]); -if ($r["result"]=="success"){ +if ($r["result"] == "success") { msg("删除成功"); -}else{ - msg("删除失败:".$r["msg"]); +} else { + msg("删除失败:" . $r["msg"]); } \ No newline at end of file diff --git a/domains.php b/domains.php index 62ea686..0a40399 100644 --- a/domains.php +++ b/domains.php @@ -4,7 +4,7 @@ $cloudflare->is_login(); -$r=$cloudflare->user_lookup(); +$r = $cloudflare->user_lookup(); include_once("header.php"); @@ -12,133 +12,140 @@ ?>
域名 | -- | - |
---|
查询失败: + = $r["msg"]; ?> + + +
无域名,赶紧添加一个吧!
+ + +查询失败: - =$r["msg"];?> - - -
无域名,赶紧添加一个吧!
- - -diff --git a/header.php b/header.php index d265540..1090236 100644 --- a/header.php +++ b/header.php @@ -3,16 +3,16 @@
-
- - - - - - - - - +
+ + + + + + + + + diff --git a/index.php b/index.php index 36fa587..152df37 100644 --- a/index.php +++ b/index.php @@ -7,69 +7,72 @@ include_once("header.php"); ?> -
- | 记录 | -CNAME记录 | -回源地址 | -
---|---|---|---|
'. - " | ".$record." | "; - if ($is_ssl) - { - echo $set; - }else{ - echo $r["forward_tos"][$record]; - } - echo ' | '.$set.' |
- 注 (1):必须设置一个www记录,否则会自动设置一个回源地址为=$r["zone_name"]?>的www记录。本记录可不在DNS服务商配置 -
-- 注 (2):根据先前的测试(2018-02-15),目前启用Universal SSL无需再专门配置CNAME记录,只需配置所需接入的域名的CNAME记录。证书将在24小时内下发。一切以实际情况为准 -
- -- 注 (3):回源地址以CNAME形式填写,暂时不支持A记录和AAAA记录 -
- ++ + | +记录 | +CNAME记录 | +回源地址 | +
---|---|---|---|
' . + " | " . $record . " | "; + if ($is_ssl) { + echo $set; + } else { + echo $r["forward_tos"][$record]; + } + echo ' | ' . $set . ' |
+ 注 + (1):必须设置一个www记录,否则会自动设置一个回源地址为= $r["zone_name"] ?>的www记录。本记录可不在DNS服务商配置 +
++ 注 (2):根据先前的测试(2018-02-15),目前启用Universal + SSL无需再专门配置CNAME记录,只需配置所需接入的域名的CNAME记录。证书将在24小时内下发。一切以实际情况为准 +
+ ++ 注 (3):回源地址以CNAME形式填写,暂时不支持A记录和AAAA记录 +
+ +