nslookup 查看域名 dns 地址

域名是需要DNS才能正常解析的。最近我有个域名在 dnspod 上老是无法解析,提示 NS 地址还未修改,头疼。于是查看了域名 dns 解析地址,易名中国真是坑(应该就是他的锅吧。

nslookup命令,是Linux里非常常用的网络命令,简而言之就是“查DNS信息用的”。 作者是Andrew Cherenson, 他是一位计算机科学的高材生,曾经就读于哈佛大学和加州大学伯克利分校。 目前就职于ChoiceStream公司。

windows 下:

nslookup -qt=ns xxx.org

显示:

服务器:  cache-nn.gxcc.net
Address:  221.7.128.68

*** cache-nn.gxcc.net 找不到 xxx: Non-existent domain

Linux 下:

nslookup

显示:

> xxx.org
Server:         100.100.2.136
Address:        100.100.2.136#53

** server can't find xxx: NXDOMAIN

如果是正确的情况,应该这么显示

服务器:  cache-nn.gxcc.net                     
Address:  221.7.128.68                                                                        

非权威应答:                                    
kelu.org        nameserver = f1g1ns2.dnspod.net
kelu.org        nameserver = f1g1ns1.dnspod.net

或者

> kelu.org
Server:         100.100.2.136
Address:        100.100.2.136#53

Non-authoritative answer:
Name:   kelu.org
Address: 47.52.46.212

启动nginx状态页

nginx 内建了一个状态页,对于想了解nginx的状态以及监控nginx非常有帮助。

在你的 nginx.conf 配置的server中添加如下配置:

location /nginx_status {
    stub_status on;
    access_log off;
    allow 192.168.10.0/24;
    deny all;
}

然后重启 nginx,即可成功。

你可能在重启的时候遇到

unknown directive "stub_status"

这是因为nginx没有加上http_stub_status_module,需要重新安装这个插件:

./configure --with-http_stub_status_module

访问该网页,可以看到类似如下的信息:

Active connections: 1998 
server accepts handled requests
1189721 1189721 2667471 
Reading: 2 Writing: 10 Waiting: 1980

说明:

  • Active connection -活跃的连接数量
  • server accepts handled requests 总共处理了1189721个连接,成功创建了1189721次握手,总共处理了2667471个请求
  • Reading——读取客户端的连接数
  • Writing——响应数据到客户端的数量
  • Waitting——开启keep-alive的情况下,这个只等于active-(Reading+Writing),意思就是nginx已经处理完正在等候下一次请求指令的驻留连接

反向代理 GitHub Pages

我的这个 blog 一直托管在 github 上。因为担心访问问题(貌似 Github 原本就是 GFW 屏蔽的?),配置了一个免费的 CDN:https://www.incapsula.com/,不得不说,其实还是不错的,可以避免访问不稳定的问题。缺点在于访问速度确实慢了,大概有1300-2000ms延迟。

手头上刚好有比较好的资源,就做了一个反向代理,效果不错,目前延迟在120-400ms,已经满足了。

配置反代也非常简单,就两步,DNS 重定向和 nginx 反代:

dns重定向

配置DNS重定向到目标服务器。

nginx

server {
    listen       80;
    server_name  blog.kelu.org;

    access_log off; #access_log end
    error_log /dev/null; #error_log end

    location / {
           proxy_pass         http://kelvinblood.github.io;
           proxy_redirect     off;
           proxy_set_header   Host                        $host;
           proxy_set_header   X-Real-IP               $remote_addr;
           proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}

配置说明:

proxy_set_header Host $host 设置请求头的Host为反向代理服务器的Host

proxy_set_header X-Real-IP $remote_addr 设置请求头的X-Real-IP为客户端真实IP

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for 把请求来源的IP添加到请求头的X-Forwarded-For字段

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP代理或者负载均衡服务器时才会添加该项。 它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。 标准格式如下:X-Forwarded-For: client1, proxy1, proxy2。

Hubot 脚本与开发文档一 中文

每次看英文文档都有点头疼,做了一些简要的翻译给自己看。 原文请看https://hubot.github.com/docs/scripting/

目录:

  • 接收和回复
  • 给指定群组或用户的消息
  • 捕获数据
  • 进行HTTP调用
  • 随机
  • Topic
  • 进入和离开聊天室
  • 自定义房间人员
  • 环境变量
  • 依赖
  • HTTP监听器
  • 事件
  • 错误处理
  • 记录脚本
  • 持久化
  • 脚本

    • 加载脚本
    • 共享脚本
  • 中间件

    • 监听中间件
    • 接收中间件
    • 回复中间件
  • 测试

正文:

安装好hubot后,根目录下会生成一个 scripts 目录,里面有个可用的 demo 文件example.coffee,大致如下:

# Description:
#   Example scripts for you to examine and try out.
#
# Notes:
#   They are commented out by default, because most of them are pretty silly and
#   wouldn't be useful and amusing enough for day to day huboting.
#   Uncomment the ones you want to try and experiment with.
#
#   These are from the scripting documentation: https://github.com/github/hubot/blob/master/docs/scripting.md

module.exports = (robot) ->

 robot.hear /kelutest/i, (res) ->
   res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS"
  #
  # robot.respond /open the (.*) doors/i, (res) ->
  #   doorType = res.match[1]
  #   if doorType is "pod bay"
  #     res.reply "I'm afraid I can't let you do that."
  #   else
  #     res.reply "Opening #{doorType} doors"

要使得你编写的script生效,需要满足一下三个条件:

  • 在scripts文件夹中
  • .coffee 或 .js 文件
  • 导出一个方法

      module.exports = (robot) ->
        # your code here
    

接收和回复

module.exports = (robot) ->
  robot.hear /badger/i, (res) ->
    res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS"

  robot.respond /open the pod bay doors/i, (res) ->
    res.reply "I'm afraid I can't let you do that."

  robot.hear /I like pie/i, (res) ->
    res.emote "makes a freshly baked pie"
  • hear 所有匹配信息
  • send 发送消息
  • respond 群组消息中只处理@自己的信息
  • reply 群组消息中回复特定人的消息

给指定群组或用户的消息

可以使用messageRoom函数发送到指定的房间或用户,可以明确地指定用户名(对于管理员/管理员),或者使用响应对象将私人消息发送到原始发件人。

  robot.respond /I don't like Sam-I-am/i, (res) ->
    room =  'joemanager'
    robot.messageRoom room, "Someone does not like Dr. Seus"
    res.reply  "That Sam-I-am\nThat Sam-I-am\nI do not like\nthat Sam-I-am"

  robot.hear /Sam-I-am/i, (res) ->
    room =  res.envelope.user.name
    robot.messageRoom room, "That Sam-I-am\nThat Sam-I-am\nI do not like\nthat Sam-I-am"

捕获数据

res.match 存有 match 传入消息与正则表达式的结果。这是一个数组,索引起始是0。比如:

  robot.respond /open the (.*) doors/i, (res) ->
    doorType = res.match[1]
    if doorType is "pod bay"
      res.reply "I'm afraid I can't let you do that."
    else
      res.reply "Opening #{doorType} doors"

进行HTTP调用

Hubot可以集成使用第三方API。 通过 node-scoped-http-client 插件的robot.http,可以进行http调用。 最简单的情况如下:

get:

   robot.http("http://blog.kelu.org")
     .get() (err, res, body) ->
       # your code here

post:

    data = JSON.stringify({
      foo: 'bar'
    })
    robot.http("http://blog.kelu.org")
      .header('Content-Type', 'application/json')
      .post(data) (err, res, body) ->
        # your code here     

处理错误:

  robot.http("https://midnight-train")
    .get() (err, res, body) ->
      if err
        res.send "Encountered an error :( #{err}"
        return
      # your code here, knowing it was successful            

如果需要处理返回头部信息,应该如下操作:

  robot.http("https://midnight-train")
    .get() (err, res, body) ->
      # pretend there's error checking code here

      if res.statusCode isnt 200
        res.send "Request didn't come back HTTP 200 :("
        return

      rateLimitRemaining = parseInt res.getHeader('X-RateLimit-Limit') if res.getHeader('X-RateLimit-Limit')
      if rateLimitRemaining and rateLimitRemaining < 1
        res.send "Rate Limit hit, stop believing for awhile"

      # rest of your code
      res.send "Got back #{body}"

json

我们可以使用 json.parse 进行解析,有可能得到非JSON,为了安全起见,应该检查Content-Type ,并在解析时捕获错误。

  robot.http("https://midnight-train")
    .header('Accept', 'application/json')
    .get() (err, res, body) ->
      # err & response status checking code here

      if response.getHeader('Content-Type') isnt 'application/json'
        res.send "Didn't get back JSON :("
        return

      data = null
      try
        data = JSON.parse body
      catch error
       res.send "Ran into an error parsing JSON :("
       return

      # your code here

xml

比较麻烦,可以参考以下几个库:

截图

参考以下库

  • cheerio (familiar syntax and API to jQuery)
  • jsdom (JavaScript implementation of the W3C DOM)

高级HTTP和HTTPS设置

如上所述,hubot使用 node-scoped-http-client 来提供一个简单的接口来进行HTTP和HTTPS请求。

如果需要更直接地控制http和https,则将第二个参数传递给robot.http ,该参数将被传递给节点robot.http -http-client,该参数将传递给http和https:

  options =
    # don't verify server certificate against a CA, SCARY!
    rejectUnauthorized: false
  robot.http("https://midnight-train", options)

如果 node-scoped-http-client 不满足需求,我们也可以直接使用http和https ,或者其他节点库(如request/request) 。

随机

lulz = ['lol', 'rofl', 'lmao']

res.send res.random lulz

Topic

可以修改房间的主题

  module.exports = (robot) ->
    robot.topic (res) ->
      res.send "#{res.message.text}? That's a Paddlin'"

进入和离开聊天室

enterReplies = ['Hi', 'Target Acquired', 'Firing', 'Hello friend.', 'Gotcha', 'I see you']
leaveReplies = ['Are you still there?', 'Target lost', 'Searching']

module.exports = (robot) ->
  robot.enter (res) ->
    res.send res.random enterReplies
  robot.leave (res) ->
    res.send res.random leaveReplies