![Openvpn --learn-address 与 nsupdate | SERVFAIL](https://linux22.com/image/724408/Openvpn%20--learn-address%20%E4%B8%8E%20nsupdate%20%7C%20SERVFAIL.png)
我尝试搜索我能找到的几乎所有地方,以找出为什么看似合法的设置不起作用。我正尝试使用--learn-address
OpenVPN 服务器的 OpenVPN 客户端存档 DDNS。DNS 服务器是 bind9。我不确定以下三件事:
- 我的名称服务器正确吗?
- 为何我收到 SERVFAIL?
- 当我 ping 587-gc2 (或 587-gc2.proxy.example.com)时,我得到了
Name or service not known
,即使我的区域文件当前是手动输入。
db.vpn 区域文件位于/var/lib/bind/
:
$ORIGIN .
$TTL 60 ; 1 minute
proxy.example.com IN SOA ns4.example.com. (
20180711 ; serial
60 ; refresh (1 minute)
120 ; retry (2 minutes)
60 ; expire (1 minute)
60 ; minimum (1 minute)
)
NS ns1.example.com.
NS ns4.example.com.
$ORIGIN proxy.example.com.
$TTL 14400 ; 4 hours
587-gc2 A 172.XX.XX.26
尝试nsupdate
查询:
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 17693
;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; ZONE SECTION:
;proxy.example.com. IN SOA
;; UPDATE SECTION:
587-gc2.proxy.example.com. 60 IN A 172.XX.XX.26
;; TSIG PSEUDOSECTION:
keyname. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1531335476 300 16 TSIGSECRET 17693 NOERROR 0
以上nsupdate
查询的答复:
Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: SERVFAIL, id: 17693
;; flags: qr; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; ZONE SECTION:
;proxy.example.com. IN SOA
;; TSIG PSEUDOSECTION:
SECRETKEY. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1531335476 300 16 TSIGSECRET 17693 NOERROR 0
重新连接设备时的完整系统日志(命名日志)
setup_system()
Creating key...
namefromtext
keycreate
reset_system()
user_interaction()
do_next_command()
message repeated 3 times: [ do_next_command()]
evaluate_update()
update_addordelete()
do_next_command()
start_update()
send_update()
Sending update to 127.0.0.1#53
show_message()
update_completed()
tsig verification successful
show_message()
Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: SERVFAIL, id: 36239
;; flags: qr; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
;; ZONE SECTION:
;proxy.example.com. IN SOA
;; TSIG PSEUDOSECTION:
SECRETKEY. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1531416897 300 16 TSIGSECRET 36239 NOERROR 0
done_update()
reset_system()
user_interaction()
cleanup()
detach tsigkey x0x7fb6a35cf0b8
Shutting down task manager
shutdown_program()
Shutting down request manager
Destroy DST lib
Destroying request manager
Freeing the dispatchers
Shutting down dispatch manager
Destroying event
Shutting down socket manager
Shutting down timer manager
Destroying hash context
Destroying name state
Removing log context
Destroying memory context
/usr/local/sbin/ 中的 --learn-address 脚本
#!/usr/bin/php
<?php
/*
* This script can be passed to --learn-address of the openvpn server, it will
* update the local bind9 server whenever an ip address is passed
*/
// Bind9 server to update
define("NS_ADDR", "127.0.0.1");
// Domain to prepend common name to
define("DOMAIN", "proxy.example.com");
// nsupdate bin
define("NSUPDATE", "/usr/bin/nsupdate");
// Temp path
define("TMP_PATH", "/tmp/");
// Private key path
define("PRIVATE_KEY", "SECRETKEY:SECRETHASH");
// Debug
define("DEBUG", true);
function failWithError($error) {
syslog(LOG_ERR, $error);
exit(1);
}
function addRecordWithIP($record, $ip) {
$domain = $record.".".DOMAIN;
$filepath = TMP_PATH."/". __FUNCTION__."_" .rand(900, 999);
$fh = fopen($filepath, "w");
fwrite($fh, "server ".NS_ADDR."\n");
fwrite($fh, "debug ".(DEBUG?'yes':'no')."\n");
fwrite($fh, "zone ".DOMAIN."\n");
fwrite($fh, "update add {$domain} 60 A {$ip}\n");
fwrite($fh, "send\n");
fclose($fh);
$output = [];
exec(NSUPDATE." -y ".PRIVATE_KEY." -D -v ".escapeshellarg($filepath).(DEBUG?"":" 2>&1 > /dev/null"), $output);
if (DEBUG) {
syslog(LOG_ERR, print_r($output, true));
}
// clean up
unlink($filepath);
}
function removeRecord($record) {
$domain = $record.".".DOMAIN;
$filepath = TMP_PATH."/". __FUNCTION__."_" .rand(900, 999);
$fh = fopen($filepath, "w");
fwrite($fh, "server ".NS_ADDR."\n");
fwrite($fh, "debug ".(DEBUG?'yes':'no')."\n");
fwrite($fh, "zone ".DOMAIN."\n");
fwrite($fh, "update delete {$domain}\n");
fwrite($fh, "send\n");
fclose($fh);
$output = [];
exec(NSUPDATE." -y ".PRIVATE_KEY." -v ".escapeshellarg($filepath).(DEBUG?"":" 2>&1 > /dev/null"), $output);
if (DEBUG) {
syslog(LOG_ERR, print_r($output, true));
}
// clean up
unlink($filepath);
}
if ($argc < 3) {
failWithError("Incorrect number of params");
}
$slashpos = strpos($argv[2], "/");
if ($slashpos !== false) {
// Remove subnet from ip
$argv[2] = substr($argv[2], $slashpos);
}
if (inet_pton($argv[2]) === false) {
failWithError("{$argv[2]} is not a valid ip address");
}
switch($argv[1]) {
case "update":
case "add":
if (isset($argv[3])) {
removeRecord($argv[3]);
addRecordWithIP($argv[3], $argv[2]);
}
break;
case "remove":
// Since openvpn only provides the ip on this request we cannot remove the
break;
}
// Success
exit(0);
named.conf.local
在/etc/bind/
:
include "/etc/bind/named.conf.log";
acl vpnnets { 172.XX.XX.XX/16; 192.168.3.0/24; };
acl ourservers { SERVERIP; };
key dhcpupdate {
algorithm hmac-md5;
secret "SECRETHASH";
};
view "vpn" {
match-clients { vpnnets;ourservers; };
recursion yes;
zone "proxy.example.com" {
type master;
file "/var/cache/bind/db.vpn";
allow-update { key SECRETKEY;};
};
include "/etc/bind/named.conf.default-zones-vpn";
allow-query { vpnnets;ourservers;any; };
allow-query-cache { vpnnets;ourservers; };
allow-recursion { vpnnets;ourservers; };
};
view "external" {
match-clients {any;};
recursion yes;
zone "proxy.example.com" {
type master;
file "/var/cache/bind/db.vpn-external";
allow-update { key SECRETKEY;};
};
};
resolv.conf
在/etc/
:
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 172.XX.XX.1
nameserver 169.254.169.254
search c.GOOGLEPROJECT.internal google.internal
从 587-gc2.proxy.example.com 挖掘输出
; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> 587-gc2.proxy.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 50282
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 3e50511a4a2fe8a1f5ba4f2d5b47943d6559b3ba4abf601e (good)
;; QUESTION SECTION:
;587-gc2.proxy.example.com. IN A
;; Query time: 46 msec
;; SERVER: 172.XX.XX.1#53(172.XX.XX.1)
;; WHEN: Thu Jul 12 12:47:41 CDT 2018
;; MSG SIZE rcvd: 86
尝试挖掘完整的 587-gc2.proxy.example.com 时,named/bind 日志
13-Jul-2018 12:49:49.445 queries: info: client @0x7f69407fa110 172.XX.XX.1#54377 (587-gc2.proxy.example.com): view vpn: query: 587-gc2.proxy.example.com IN A +E(0)K (172.XX.XX.1)
13-Jul-2018 12:49:49.445 query-errors: info: client @0x7f69407fa110 172.XX.XX.1#54377 (587-gc2.proxy.example.com): view vpn: query failed (SERVFAIL) for 587-gc2.proxy.example.com/IN/A at ../../../bin/named/query.c:6984
答案1
当您尝试 nsupdate 命令时,从时间窗口查看命名日志也会非常有帮助。对我来说,更新过程中似乎存在问题。SERVERFAIL 响应表示存在问题。NOERROR 很可能与加密有关。