Loading...
Loading...
Compare original and translation side by side
Skill by ara.so — Daily 2026 Skills collection.
quienwhois来自ara.so的技能——Daily 2026 Skills合集。
quienwhoisbrew tap retlehs/tap
brew install retlehs/tap/quiencurl -fsSL https://apt.quien.dev/install.sh | sudo shgo install github.com/retlehs/quien@latestquien --versionundefinedbrew tap retlehs/tap
brew install retlehs/tap/quiencurl -fsSL https://apt.quien.dev/install.sh | sudo shgo install github.com/retlehs/quien@latestquien --versionundefined
---
---undefinedundefinedundefinedundefinedundefinedundefined
---
---| Tab | Data shown |
|---|---|
| WHOIS | RDAP-first registration data, registrar, dates, nameservers |
| DNS | A, AAAA, MX, TXT, NS, CNAME, SOA records |
| MX, SPF, DMARC, DKIM, BIMI + VMC chain validation | |
| TLS | Certificate chain, validity, SANs, cipher info |
| HTTP | Response headers, redirects, status codes |
| Stack | WordPress plugins, JS/CSS frameworks, external services |
| IP | Reverse DNS, network info, abuse contacts, ASN via RDAP/BGP |
| 标签页 | 展示的数据 |
|---|---|
| WHOIS | 优先显示RDAP注册数据、注册商、日期、域名服务器 |
| DNS | A、AAAA、MX、TXT、NS、CNAME、SOA记录 |
| 邮件 | MX、SPF、DMARC、DKIM、BIMI + VMC证书链验证 |
| TLS | 证书链、有效期、SANs、加密套件信息 |
| HTTP | 响应头、重定向、状态码 |
| 技术栈 | WordPress插件、JS/CSS框架、外部服务 |
| IP | 反向DNS、网络信息、滥用联系信息、通过RDAP/BGP获取的ASN |
quien dns github.comquien dns github.comundefinedundefinedquien mail example.comquien mail example.comundefinedundefinedquien tls example.comquien tls example.comundefinedundefinedquien http example.comquien http example.comundefinedundefinedquien stack example.comquien stack example.comundefinedundefinedquien 8.8.8.8
quien --json 8.8.8.8quien 8.8.8.8
quien --json 8.8.8.8undefinedundefinedquien all example.com | jq '.dns.a'
quien all example.com | jq '.mail.spf'
quien all example.com | jq '.tls.valid_until'quien all example.com | jq '.dns.a'
quien all example.com | jq '.mail.spf'
quien all example.com | jq '.tls.valid_until'undefinedundefinedundefinedundefined#!/bin/bash
domains=("example.com" "github.com" "golang.org")
for domain in "${domains[@]}"; do
echo "=== $domain ==="
spf=$(quien mail "$domain" | jq -r '.spf.record // "MISSING"')
dmarc=$(quien mail "$domain" | jq -r '.dmarc.policy // "MISSING"')
tls_expiry=$(quien tls "$domain" | jq -r '.certificates[0].not_after // "N/A"')
echo "SPF: $spf"
echo "DMARC: $dmarc"
echo "TLS expires: $tls_expiry"
echo
done#!/bin/bash
domains=("example.com" "github.com" "golang.org")
for domain in "${domains[@]}"; do
echo "=== $domain ==="
spf=$(quien mail "$domain" | jq -r '.spf.record // "MISSING"')
dmarc=$(quien mail "$domain" | jq -r '.dmarc.policy // "MISSING"')
tls_expiry=$(quien tls "$domain" | jq -r '.certificates[0].not_after // "N/A"')
echo "SPF: $spf"
echo "DMARC: $dmarc"
echo "TLS过期时间: $tls_expiry"
echo
done#!/bin/bash
DOMAIN="${1:?Usage: $0 <domain>}"
expiry=$(quien --json "$DOMAIN" | jq -r '.whois.expires // .rdap.expires // empty')
if [ -z "$expiry" ]; then
echo "Could not determine expiry for $DOMAIN"
exit 1
fi
echo "$DOMAIN expires: $expiry"#!/bin/bash
DOMAIN="${1:?用法: $0 <域名>}"
expiry=$(quien --json "$DOMAIN" | jq -r '.whois.expires // .rdap.expires // empty')
if [ -z "$expiry" ]; then
echo "无法确定$DOMAIN的过期时间"
exit 1
fi
echo "$DOMAIN过期时间: $expiry"package main
import (
"encoding/json"
"fmt"
"os/exec"
)
type DNSResult struct {
Domain string `json:"domain"`
A []string `json:"a"`
MX []struct {
Host string `json:"host"`
Priority int `json:"priority"`
} `json:"mx"`
TXT []string `json:"txt"`
}
func lookupDNS(domain string) (*DNSResult, error) {
out, err := exec.Command("quien", "dns", domain).Output()
if err != nil {
return nil, fmt.Errorf("quien dns failed: %w", err)
}
var result DNSResult
if err := json.Unmarshal(out, &result); err != nil {
return nil, fmt.Errorf("parse error: %w", err)
}
return &result, nil
}
func main() {
dns, err := lookupDNS("example.com")
if err != nil {
panic(err)
}
fmt.Printf("A records for %s: %v\n", dns.Domain, dns.A)
for _, mx := range dns.MX {
fmt.Printf("MX %d: %s\n", mx.Priority, mx.Host)
}
}package main
import (
"encoding/json"
"fmt"
"os/exec"
)
type DNSResult struct {
Domain string `json:"domain"`
A []string `json:"a"`
MX []struct {
Host string `json:"host"`
Priority int `json:"priority"`
} `json:"mx"`
TXT []string `json:"txt"`
}
func lookupDNS(domain string) (*DNSResult, error) {
out, err := exec.Command("quien", "dns", domain).Output()
if err != nil {
return nil, fmt.Errorf("quien dns执行失败: %w", err)
}
var result DNSResult
if err := json.Unmarshal(out, &result); err != nil {
return nil, fmt.Errorf("解析错误: %w", err)
}
return &result, nil
}
func main() {
dns, err := lookupDNS("example.com")
if err != nil {
panic(err)
}
fmt.Printf("%s的A记录: %v\n", dns.Domain, dns.A)
for _, mx := range dns.MX {
fmt.Printf("MX优先级%d: %s\n", mx.Priority, mx.Host)
}
}package main
import (
"encoding/json"
"os/exec"
)
type FullAudit struct {
WHOIS struct {
Registrar string `json:"registrar"`
Created string `json:"created"`
Expires string `json:"expires"`
Updated string `json:"updated"`
} `json:"whois"`
DNS struct {
A []string `json:"a"`
NS []string `json:"ns"`
TXT []string `json:"txt"`
} `json:"dns"`
Mail struct {
SPF struct {
Record string `json:"record"`
Valid bool `json:"valid"`
} `json:"spf"`
DMARC struct {
Record string `json:"record"`
Policy string `json:"policy"`
} `json:"dmarc"`
} `json:"mail"`
TLS struct {
Certificates []struct {
Subject string `json:"subject"`
NotAfter string `json:"not_after"`
} `json:"certificates"`
} `json:"tls"`
Stack struct {
JavascriptFrameworks []string `json:"javascript_frameworks"`
CSSFrameworks []string `json:"css_frameworks"`
ExternalServices []string `json:"external_services"`
} `json:"stack"`
}
func auditDomain(domain string) (*FullAudit, error) {
out, err := exec.Command("quien", "all", domain).Output()
if err != nil {
return nil, err
}
var audit FullAudit
return &audit, json.Unmarshal(out, &audit)
}package main
import (
"encoding/json"
"os/exec"
)
type FullAudit struct {
WHOIS struct {
Registrar string `json:"registrar"`
Created string `json:"created"`
Expires string `json:"expires"`
Updated string `json:"updated"`
} `json:"whois"`
DNS struct {
A []string `json:"a"`
NS []string `json:"ns"`
TXT []string `json:"txt"`
} `json:"dns"`
Mail struct {
SPF struct {
Record string `json:"record"`
Valid bool `json:"valid"`
} `json:"spf"`
DMARC struct {
Record string `json:"record"`
Policy string `json:"policy"`
} `json:"dmarc"`
} `json:"mail"`
TLS struct {
Certificates []struct {
Subject string `json:"subject"`
NotAfter string `json:"not_after"`
} `json:"certificates"`
} `json:"tls"`
Stack struct {
JavascriptFrameworks []string `json:"javascript_frameworks"`
CSSFrameworks []string `json:"css_frameworks"`
ExternalServices []string `json:"external_services"`
} `json:"stack"`
}
func auditDomain(domain string) (*FullAudit, error) {
out, err := exec.Command("quien", "all", domain).Output()
if err != nil {
return nil, err
}
var audit FullAudit
return &audit, json.Unmarshal(out, &audit)
}npx skills add retlehs/quiennpx skills add retlehs/quienquien: command not foundundefinedquien: command not foundundefined
**TUI doesn't render correctly**
```sh
**TUI无法正确渲染**
```sh
**Rate limiting / lookup failures**
- RDAP and WHOIS servers may rate-limit. quien retries with backoff automatically.
- For bulk scripting, add `sleep 1` between calls to avoid hitting rate limits.
**No DKIM results**
- DKIM requires knowing the selector. quien probes common selectors (google, default, mail, etc.) but custom selectors won't be discovered automatically.
**IP lookup shows no ASN**
- Some IP blocks are not in RDAP. quien falls back to BGP; if both fail, the block may be unrouted or private.
**JSON output is empty / malformed**
```sh
**速率限制/查询失败**
- RDAP和WHOIS服务器可能会限制速率。quien会自动使用退避策略重试。
- 批量脚本执行时,在两次调用之间添加`sleep 1`以避免触发速率限制。
**无DKIM结果**
- DKIM需要知道选择器。quien会探测常见选择器(google、default、mail等),但自定义选择器无法自动发现。
**IP查询未显示ASN**
- 某些IP块未收录在RDAP中。quien会回退到BGP查询;如果两者都失败,该IP块可能未路由或为私有IP。
**JSON输出为空/格式错误**
```shundefinedundefined