(原文在这里)[https://stray.love/itshou-zha/wei-aria2-tian-jia-tracker-fu-wu-qi]

把下面脚本放入定时任务,然后通过rpc更新 ,简单方便快捷

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
#more trackers list, see https://github.com/ngosang/trackerslist

tracker_url='https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt'
path='http://10.10.10.5:6800/jsonrpc'
passwd='xxxxxx'

tracker=$(echo -n $(curl -s -L $tracker_url | sed 'N;s/\n//g') | tr ' ' ',')
[ -n "$tracker" ] && curl $path -d '{"jsonrpc":"2.0","method":"aria2.changeGlobalOption","id":"cron","params":["token:'$passwd'",{"bt-tracker":"'$tracker'"}]}'

利用猫盘做一个下载机,其实也没什么东西要下载,迅雷都可以,干嘛还要做这样一台机呢? 折腾罢了. aria2下载速度远远不如迅雷的,但是还要折腾这个,还是有一点比迅雷好的地方的,就是可以利用晚上时间下载.

猫盘刷debin系统, 不表.

fireware在这里

然后apt instll aria2 nginx等组件.

airaNg 的要手动下载,apt 安装不了.

重点说配置把,aria2 最重要就是配置文件,这个网上有, 主要事要做一个service加入系统服务中
在/etc/systemd/system 下面做一个aira2.service文件

1
2
3
4
5
6
7
8
9
[Unit]
Description=Aria2 Service
After=network.target

[Service]
ExecStart=aria2c --enable-rpc=true --input-file=/root/aria2/aria2.session --conf-path=/root/aria2/aria2.conf

[Install]
WantedBy=multi-user.target

必须放入/etc/systemd/system中,不要放入user文件夹中 ,会导致退出登录后无法连接到airaNg的问题.

ariaNg 下载后/var/www/html/下面 ,不要放到其他地方,如果放到其他地方,nginx 要配置,当然如果你会配nginx,当我没说. 我比较懒,就不配了,自己放入,然后就可以访问.

curl 不单单是下载工具,还可以上传,支持众多协议.
我有一个摄像头接在ar9331 上面,跑mjpeg-stream,主要是拍照,监控淋花的情况,每天拍一张都两张照片,为什么不用现成的摄像头呢? 其实也可以,不过了,一来做来玩玩,另外一个可以把多年照片存起来,这个还是有点意思.

不说废话

在公司内网开内一个ftp服务器, 要端口映射到外网,这里面有点技巧,
ftp现在都是加密的,要不然就太不安全. 必须ssh.

内网ftp服务器vsftpd的设置

/etc/vsftpd.conf 关键地方我用中文标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# Example config file /etc/vsftpd.conf
#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
#
# Run standalone? vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
listen=Yes 关闭ipv6 后必须打开这个
#
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
listen_ipv6=No 必须关闭ipv6 ,否则最后传不到实际外网的ip地址
#
# Allow anonymous FTP? (Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
local_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# If enabled, vsftpd will display directory listings with the time
# in your local time zone. The default is to display GMT. The
# times returned by the MDTM FTP command are also affected by this
# option.
use_localtime=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
#xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd.banned_emails
#
# You may restrict local users to their home directories. See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
#chroot_local_user=YES
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
chroot_local_user=YES
#chroot_list_enable=YES
# (default follows)
chroot_list_file=/etc/vsftpd.chroot_list
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# Customization
#
# Some of vsftpd's settings don't fit the filesystem layout by
# default.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd/empty
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
rsa_cert_file=/etc/ssl/certs/xxxxx.pem
rsa_private_key_file=/etc/ssl/private/xxxx.key
ssl_enable=Yes
force_local_data_ssl=Yes
force_local_logins_ssl=Yes
ssl_tlsv1=Yes

#
# Uncomment this to indicate that vsftpd use a utf8 filesystem.
utf8_filesystem=YES

userlist_enable=Yes
userlist_deny=No
userlist_file=/etc/vsftpd.user_list
allow_writeable_chroot=Yes

pasv_enable=Yes
listen_port=??? //看需要
pasv_max_port=???? //看需要
pasv_min_port=???? //看需要
pasv_addr_resolve=Yes // 必须用这个 , 否则下面要填实际ip,但是动态ip怎么可能有ip , 这是pasv 模式下,回传给客户段的ip地址,
pasv_address=abc.com // 可以填域名,必须有上面那个yes

然后把端口映射一下.

然后利用curl 上传,curl 是支持加密ftp的.

1
2
curl -k --ftp-ssl --ftp-ssl-reqd --ftp-create-dirs -T xxx.jpg -u user:password ftp://abcd.com:1000/

-k 是忽略证书检查, 是ftp:// 不是ftps.

要提取702N 后64K的art部分 ,需要用hex editor, vscode 有一个hexdump的插件,不过不能复制截取, notepad++ 也有hexeditor的插件,不过搞来搞去都安装不成功,算了,那些事情就不说了,安装成功后,也没什么用,也非常不稳定,一下崩了.

最后还是用 HxD 这个免费的hex editor.

当然ultraEdit 也可以, 不过不免费,我也懒得用了.

PC

用时间作为文件夹和文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh

folder=$(date "+%Y%m%d")
filename=$(date "+%Y%m%d%H%M%S.jpg")
#echo $filename $folder

if test -e /mnt/sda1/$folder
then
echo "folder exits"
else
mkdir /mnt/sda1/$folder
fi

wget --o /mnt/sda1/$folder/$filename http://localhost:8080/?action=snapshot

之前淋花, 控制灯的开关 都是nodemcu 做的,但是都是基于cron服务. 也就是定时服务. 定时服务简单,就是一个缺点,有时候这些东西要修改的时候比较麻烦, 要接上串口修改, 不接上串口 ,用telnet 去改也就可以但是总没那么直观,很容易出错而不知.

上去家中花严重缺水, 原来上次淋花器的一个程序有问题, 自己修改的时候不够细心,出错,倒是一个多月缺水, 于是下定决心修改一下.

现在把所有控制器都改到用mqtt协议连接到mqtt server上面, mqtt server 是自己搭建的. 运行在一个openwrt路由器上, 域名是阿里云域名,然后自己动态更新. 电信网络有公网IP ,于是就有了一些列的服务.

nodemcu 连接到mqtt server 上面,然后所有动作,都由服务器的cron 服务统一操作. 这样随时可以修改动作的时间,内容. 方便多了. 具体来说, 而且还可以根据当天天气清空改变淋花次数, 改变喂鱼机投喂次数, 比如天气寒冷,停止投喂.

代码
init.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
--init for water 

gpio.mode(5, gpio.OUTPUT);
--gpio.mode(4, gpio.OUTPUT);
gpio.write(5, gpio.LOW);

station_cfg={}
station_cfg.ssid="sdfasd";
station_cfg.pwd="fasdfa"

-- 标识mqtt是否已经初始化
mqtt_inited = 0

-- 标识mqtt 是否已经连接
mqtt_connecting = 0



function startup()
-- if file.open("init.lua") == nil then
--print("init.lua deleted or renamed")
--else
--print("Running")
--file.close("init.lua")
-- the actual application is stored in 'application.lua'
-- dofile("application.lua")
--end
dofile("synctime.lua");


mdns.register("water", {hardware='NodeMCU'});
print("mdns:water.local/");

print("connecting mqtt server");
dofile("mqtt.lua")
end


-- Define WiFi station event callbacks
wifi_connect_event = function(T)
print("Connection to AP("..T.SSID..") established!")
print("Waiting for IP address...")
if disconnect_ct ~= nil then disconnect_ct = nil end
end

wifi_got_ip_event = function(T)
-- Note: Having an IP address does not mean there is internet access!
-- Internet connectivity can be determined with net.dns.resolve().
print("Wifi connection is ready! IP address is: "..T.IP)
print("Startup will resume momentarily, you have 3 seconds to abort.")
print("Waiting...")
tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end

wifi_disconnect_event = function(T)
if T.reason == wifi.eventmon.reason.ASSOC_LEAVE then
--the station has disassociated from a previously connected AP
return
end
-- total_tries: how many times the station will attempt to connect to the AP. Should consider AP reboot duration.
local total_tries = 5000
print("\nWiFi connection to AP("..T.SSID..") has failed!")

wifi_connetion1=0;

--There are many possible disconnect reasons, the following iterates through
--the list and returns the string corresponding to the disconnect reason.
for key,val in pairs(wifi.eventmon.reason) do
if val == T.reason then
print("Disconnect reason: "..val.."("..key..")")
break
end
end

--if disconnect_ct == nil then
-- disconnect_ct = 1
-- else
--disconnect_ct = disconnect_ct + 1
--end
--if disconnect_ct < total_tries then
-- print("Retrying connection...(attempt "..(disconnect_ct+1).." of "..total_tries..")")
--else
-- wifi.sta.disconnect()
--print("Aborting connection to AP!")
--disconnect_ct = nil
--end
end

-- Register WiFi Station event callbacks
wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_disconnect_event)

print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(station_cfg)
wifi.sta.autoconnect(1)
-- wifi.sta.connect() not necessary because config() uses auto-connect=true by default



dofile("http.lua");
print("runing http");
dofile("task.lua");
print("runing cron task");
dofile("telnet.lua");
print("runing telnet server");


mqtt.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119



function stopReconnect()
-- clear connecting state and clear connect timer!
mqtt_connecting = 0
tmr.stop(3)
end

-- 重连方法
function reconnect()
if mqtt_connecting == 0 then
tmr.alarm(3, 20000, 1, function()
print("start mqtt server reconnect!")
mq:close()
mq:connect("x.x.x.x", 1883, 0)
end)
mqtt_connecting = 1
end
end



-- 初始化mqtt连接方法
function init()
print("init mqtt")
mqtt_inited = 1
-- 初始化无需登陆的客户端, 心跳时间 120秒
mq = mqtt.Client("recv_earth1", 120)

--mq:lwt("/lwt", "offline", 0, 0)
-- 设置连接ip 以及 端口

-- 对于 TLS: m:connect("192.168.11.118", secure-port, 1)
mq:connect("192.168.1.1", 1883, 0,
function(client)
print("connected")
end,
function(client, reason)
print("failed reason: " .. reason)
reconnect()
end
)

--连接到服务器触发事件
mq:on("connect", function(client)
print("connected")
stopReconnect()
mq:subscribe("tai3_water",0, function(conn) print("subscribe success") end)
--mq:subscribe("rpt_temp",0, function(conn) print("subscribe success") end)

end)



mq:on("offline", function(client)
print ("offline")
reconnect()
end) --掉线触发事件


-- 收到消息时触发事件
mq:on("message", function(client, topic, data)
print(topic .. ":" )
if data ~= nil then
if topic == "tai3_water" then
print(data)
if data == "water1min" then
dofile("water.lua")
--mq:publish("report_info","tai3_water1",0,0)
elseif data == "water2min" then
dofile("water2.lua")
--mq:publish("report_info","tai3_water2",0,0)
elseif data == "water4min" then
dofile("water4.lua")
--mq:publish("report_info","tai3_water4",0,0)
end
end

--if topic == "rpt_water" and tonumber(data) > 12 then
--print("aaa"..data)
--end

end
end)

end




--function do_get_adc() -- 定义定时器处理函数
--mq:publish("rpt_water", adc.read(0), 0, 0)
--end

--tmr.create():alarm(60000, tmr.ALARM_AUTO , do_get_adc)

-- 确保subscribe/publish方法在连接上服务器后再调用,在实际应用中是把他们放在connect回调函数里或者确定连接成功

-- 订阅/topic主题、服务质量为0
--m:subscribe("topicxx",0, function(conn) print("subscribe success") end)
--m:subscribe("blinkdr",0, function(conn) print("subscribe success") end)
-- 发送一条信息 data = hello, QoS = 0, retain = 0

--m:close();
-- 你可以再次调用 m:connect 连接函数





-- 如果没有初始化过,进行初始化
if mqtt_inited == 0 then
init()
else
reconnect()
end


synctime.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
local tm
local sec

sec=rtctime.get();
rtctime.set(0);
sntp.sync("ntp1.aliyun.com",
function() -- success
rtctime.set(rtctime.get() + 8*3600 , 0)
tm = rtctime.epoch2cal(rtctime.get())
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
end,
function() -- fail
rtctime.set(sec);
print("fail!");
end

)

task.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
cron.schedule("1 5 */2 * *", function(e)
dofile("synctime.lua");
end)

--cron.schedule("*/15 * * * *", function(e)
-- dofile("imap_read.lua");
--end)


cron.schedule("1 8 * * *", function(e)
if mqtt_connecting == 1 then
dofile("water2.lua");
end
end)

--cron.schedule("1 9 * * *", function(e)
-- dofile("water.lua");
--end)


cron.schedule("1 11 * * *", function(e)
if mqtt_connecting == 1 then
dofile("water2.lua");
end
end)


--cron.schedule("1 12 * * *", function(e)
-- dofile("water.lua");
--end)


cron.schedule("30 17 * * *", function(e)
if mqtt_connecting == 1 then
dofile("water2.lua");
end
end)


--cron.schedule("30 18 * * *", function(e)
--dofile("water.lua");
--end)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/sh

# check ip change and update it



ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"



ipaddr=$(ifconfig pppoe-wan | awk '/inet /{print $2}' |grep -o "$ip_regex" )

old_ipaddr=$(ping -c 1 kang.ddns.info|head -1 | grep -o "$ip_regex")





if [ "$ipaddr" != "$old_ipaddr" ];then


# 发邮件
echo "Subject:$ipaddr" | ssmtp -v robot12123@334343.net

# 更新
wget -q -O /tmp/ddns --no-check-certificate 'https://nic.changeip.com/nic/update?u=XXX&p=XXX&hotname=kk'



fi

wr842n 缩水很严重, 把ram拆下来改成64MB , flash 改成25Q128 16m 版本, 当然,芯片要用编程序写入breed, 然后再焊上去, 结果写入固件后不断重启, 查来查去 ,原来没有烧入art 文件

art 是无线部分的特性参数的文件,网上做breed的大神有, 我是下载来的,我提供一份把,这里

原链接在这里

在breed 中更新qca9533的art文件后,正常启动.

固件?
固件就是opwnwrt 官网固件,我写入是18.XX版本, 我是用来做MTQQ server 的, 所以其他功能没有测试.

ssmtp 是一个简单发邮件工具,

配置/etc/ssmtp/ssmtp.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#
# /etc/ssmtp.conf -- a config file for sSMTP sendmail.
#

# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=robot123456@kaudioxxyyzz.net

# The place where the mail goes. The actual machine name is required
# no MX records are consulted. Commonly mailhosts are named mail.domain.com
# The example will fit if you are in domain.com and your mailhub is so named.
mailhub=smtp.kaudioxxyyzz.net

# Example for SMTP port number 2525
# mailhub=mail.your.domain:2525
# Example for SMTP port number 25 (Standard/RFC)
# mailhub=mail.your.domain
# Example for SSL encrypted connection
# mailhub=mail.your.domain:465

# Where will the mail seem to come from?
rewriteDomain=kaudioxxyyzz.net

# The full hostname
hostname=kaudioxxyyzz.net

# Set this to never rewrite the "From:" line (unless not given) and to
# use that address in the "from line" of the envelope.
FromLineOverride=YES

# Use SSL/TLS to send secure messages to server.
#UseTLS=YES

# Use SSL/TLS certificate to authenticate against smtp host.
#UseTLSCert=YES

# Use this RSA certificate.
#TLSCert=/etc/ssl/certs/ssmtp.pem

# Get enhanced (*really* enhanced) debugging information in the logs
# If you want to have debugging of the config file parsing, move this option
# to the top of the config file and uncomment
#Debug=YES



AuthUser=robot1234576@kaudioxxyyzz.net
AuthPass=pw

/etc/ssmtp/revaliases

1
2
3
4
5
6
7
8
9
# sSMTP aliases
#
# Format: local_account:outgoing_address:mailhub
#
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
# where [:port] is an optional port number that defaults to 25.

root:robot1111111@kaudiofdsafasd.net:smtp.kaudioafsdfasdf.net

原文章在

不过我尝试安装openwrt 路由器上

首先openwrt 的路由器空间必须大,我是安装在u盘上的,可能要10M左右空间 ,python安装也占不少空间.

程序中用到阿里云的库, aliyunsdkcore 和aliyunsdkalidns , 之前有人用pip 安装,但是openwrt 上不能, 所以下载其源码,然后解压后, 把里面核心代码复制到 /usr/lib/python2.7/XXXX (后面路径不记得) ,我看见别人自己提取相关几个文件,放在当前目录也可以.

update_ip.py 这个基本上来自前面那个文章,只不过我因为跑在openwrt上, 所以我改了获取ip的方式,改有get_ip这个脚本获取.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python
# coding= utf-8

import subprocess
import os
import json
#from urllib2 import urlopen
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest

class DnsHandler:
# 从阿里云开发者后台获取Access_Key_Id和Access_Key_Secret
access_key_id = ""
access_key_secret = ""
region_id = "cn-hangzhou"


# 填入自己的域名
domain_name = ""
# 填入二级域名的RR值
rr_keyword = ""

# 解析记录类型,一般为A记录
record_type = "A"

# 用于储存解析记录的文件名
file_name = ".ip_addr"

client = None
record = None
current_ip = ''

# 初始化,获取client实例
def __init__(self):
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region_id
)
self.record = self.get_record()
self.current_ip = self.get_current_ip()

# 如果公网IP发生变化,则自动修改阿里云解析记录
def reset(self):
if self.current_ip <> self.get_record_value():
# print self.current_ip
print self.update_record(self.current_ip)
self.get_record()

# 获取阿里云域名解析完整记录,并使用文件缓存
def get_record(self):
if os.path.isfile(self.file_name) :
file_handler = open(self.file_name, 'r')
r = file_handler.read()
file_handler.close()
else :
request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
request.set_PageSize(10)
request.set_action_name("DescribeDomainRecords")
request.set_DomainName(self.domain_name)
request.set_RRKeyWord(self.rr_keyword)
request.set_TypeKeyWord(self.record_type)
r = self.client.do_action_with_exception(request)
file_handler = open(self.file_name, 'w')
file_handler.write(r)
file_handler.close()
return json.loads(r)

# 获取阿里云域名解析记录ID
def get_record_id(self) :
return self.record["DomainRecords"]["Record"][0]["RecordId"]

# 获取当前域名解析记录
def get_record_value(self) :
return self.record["DomainRecords"]["Record"][0]["Value"]

# 修改阿里云解析记录
def update_record(self, value):
request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
request.set_action_name("UpdateDomainRecord")
request.set_RecordId(self.get_record_id())
request.set_Type(self.record_type)
request.set_RR(self.rr_keyword)
request.set_Value(value)
return self.client.do_action_with_exception(request)

# 获取当前公网IP
def get_current_ip(self):
#ip,retcode=os.system('./get_ip')
out_bytes=subprocess.check_output('/root/get_ip')
out_text= out_bytes.decode('utf8')
out_text=out_text.replace("\n","")
#print out_text
#out_text.replace("\n","").replace("\r","")
return out_text
# //json.load(urlopen('http://jsonip.com'))['ip'


# 实例化类并启动更新程序
dns = DnsHandler()
dns.reset()

1
2
3
4
5
6
7
8
9

#!/bin/sh
# check ip change and update it

ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"

ipaddr=$(ifconfig pppoe-wan | awk '/inet /{print $2}' |grep -o "$ip_regex" )

echo $ipaddr

然后加到cron 里面
*/15 * * * * python /root/update_ip.py