V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yamada
V2EX  ›  Android

使用 iptables 转发 DNS

  •  
  •   yamada · 2015-12-14 23:43:22 +08:00 · 9824 次点击
    这是一个创建于 3061 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在 iptables 添加了如下两条规则:
    iptables -t nat -A OUTPUT -m owner --uid-owner {0} -j RETURN
    iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 1111

    将 DNS 转发到了我自己的程序(监听 1111 ),然后在我自己的程序里面从 UDP 包里拆出了域名,并且再调用 InetAddress.GetByName(domain).HostAddress 希望能再利用系统自己的 DNS 解析出 IP (我扮演了一个代理的角色),但是发现这个调用又被转发到了自己于是形成了无限递归,可是我第一条规则应该已经跳过了自己发出的任何数据包啊,代理 80 之类的都是没问题的,不知道为什么 DNS 会这样

    23 条回复    2015-12-18 22:04:19 +08:00
    ryd994
        1
    ryd994  
       2015-12-15 00:02:47 +08:00 via Android
    1.你用 uid0 , root 干这种事情真的不要紧么?
    2. 既然有 root ,直接改 DNS 不是更好吗?
    3.udp 不一定有 socket owner 这个概念,或者 iptables 不一定能查到
    yamada
        2
    yamada  
    OP
       2015-12-15 00:31:34 +08:00
    @ryd994
    1 、不要紧
    2 、我想要记录下所有的 DNS 解析,包括要解析的域名和解析后的 IP 地址,目前只能这样尝试,也试过 pdnsd 和 dnsmasq ,前者输出日志没解析出来的 IP ,后者根本不输出日志
    3 、看来我只能把这个域名通过 HTTP 发送到远程去解析?
    ryd994
        3
    ryd994  
       2015-12-15 00:51:14 +08:00
    @yamada 1.任何服务都不该用 root 跑……
    2.自己软件监听 udp53 ,设置 dns 为本地不行么
    3.你还可以 tcp dns
    yamada
        4
    yamada  
    OP
       2015-12-15 08:12:05 +08:00 via Android
    @ryd994 设置本地 dns 怎么获取解析记录?
    pagxir
        5
    pagxir  
       2015-12-15 08:53:37 +08:00 via Android
    哦, Android 里其实是由 dnsmasq 进程最后发请求给远端的 dns 服务器的。所以需要将该进程处理下,否则就 loopback 回来了。
    hellogbk
        6
    hellogbk  
       2015-12-15 09:24:12 +08:00
    不是太了解 iptables ,不过我记得可以在过滤数据包的时候匹配到进程的 ID 吧? 如果发现是你的代理程序的进程,那么直接 RETURN 不进行 REDIRECT 这样行不行?
    ryd994
        7
    ryd994  
       2015-12-15 10:12:05 +08:00
    @yamada 想想 dnsmasq 之类的本地缓存服务是怎么处理的?
    简单一点就不解析,直接转发 udp 数据就好了啊
    lhbc
        8
    lhbc  
       2015-12-15 11:05:22 +08:00 via Android
    1111 端口的进程用另外一个用户跑试试。
    dnsmasq 记录日志妥妥的,毫无问题。
    yamada
        9
    yamada  
    OP
       2015-12-15 11:27:25 +08:00
    @hellogbk
    就是这样做的,看我第一条规则,但是我自己程序内部调用 InetAddress.GetByName 还是会转回到我自己
    @pagxir
    现在我没有使用 dnsmasq ,而是自己监听 1111 得到了 dns upd 包,拆出了要解析的域名,然后调用 InetAddress.GetByName(domain).HostAddress ,然后 loopback 了
    @lhbc
    之前我也尝试过 dnsmasq , dnsmasq 跑在 android 上面,这是我的配置

    log-queries
    log-facility=/data/data/xxx/dnsmasq.log
    log-async=1
    no-resolv
    no-poll
    server=114.114.114.114
    listen-address=127.0.0.7
    interface=lo
    pid-file=/data/data/xxxx/dnsmasq.pid

    dnsmasq 启动的时候 dnsmasq.log 会自动生成,但是里面永远是空的……不知道为什么
    pagxir
        10
    pagxir  
       2015-12-15 11:44:56 +08:00 via Android
    我是说这个调用 InetAddress.GetByName(domain).HostAddress 会最终跑到 dnsmasq 进程处理。除非你不是只 andriod 设备。
    pagxir
        11
    pagxir  
       2015-12-15 11:46:13 +08:00 via Android
    andriod 自己是用 dnsmasq 缓存域名的。
    yamada
        12
    yamada  
    OP
       2015-12-15 12:58:24 +08:00
    @pagxir 所以我需要--uid-owner return 掉 dnsmasq 么?但是我在 ps|grep dns 里找不到 dnsmasq 的进程,不知道该怎么过滤他……
    Jeansh
        13
    Jeansh  
       2015-12-15 13:08:03 +08:00
    bind 的 dns cache 可以吧
    服务器上跑 bind 只转发 dns 请求并回复
    可以记录

    所有-p udp --dport 53 重定向到本机的 bind 监听端口就行
    Jeansh
        14
    Jeansh  
       2015-12-15 13:08:36 +08:00
    CHAIN 是 FORWARD 才对吧?
    Jeansh
        15
    Jeansh  
       2015-12-15 13:12:08 +08:00
    应该这样吧 nat 表, 路由前:
    iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 1111
    Jeansh
        16
    Jeansh  
       2015-12-15 13:13:21 +08:00
    添加在 output 链已经晚了。
    fxxkgw
        17
    fxxkgw  
       2015-12-15 13:22:22 +08:00
    赞同 LZ 上 转发端口或者 IP 的话 需要用 PREROUTING 而不是 OUTPUT
    yamada
        18
    yamada  
    OP
       2015-12-15 15:57:35 +08:00
    @Jeansh
    iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 1111
    使用这个以后在 3G\4G 下根本就没转发过来了……
    iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:8153
    使用这个在 3G\4G 下也有问题,连接过来的是一个远程的 IP 地址……

    在 WIFI 下都可以
    yamada
        19
    yamada  
    OP
       2015-12-15 16:07:31 +08:00
    不好意思避免误会解释一下,上面的 1111 和 8153 都是示例,只是为了说明,并不是因为这个导致的错误
    Jeansh
        20
    Jeansh  
       2015-12-15 16:46:15 +08:00
    @yamada
    肯定是 PREROUTING 链
    3G/4G ?这个是不是存在有些经过 NAT 的网段?
    或者有些需要手动添加路由的非直连子网(段)?
    Sacore
        21
    Sacore  
       2015-12-16 01:44:58 +08:00 via iPhone
    3g/4g 。。不会是搞免流代理吧。。
    yamada
        22
    yamada  
    OP
       2015-12-16 14:28:16 +08:00
    @Sacore 不是

    @Jeansh 我不是很懂 NAT 网段这些,不好意思……现在在 WIFI 下测试 OK 但是 4G\3G 下也会受到 DNS UDP 的查询但远程地址是一个公网 IP ……看起来像是出了手机在外面绕了一圈后再回来的……
    yamada
        23
    yamada  
    OP
       2015-12-18 22:04:19 +08:00
    应用里面对 https 的调用,证书是不是不认 SAN ?我自签 CA 已添加到系统信任里,然后用它再签发其他的证书来做中间人响应应用里面的 HTTPS ,在浏览器里面没问题不会提示证书错误,但应用不行,试了好几个都报错,应该是证书错误
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2208 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:17 · PVG 12:17 · LAX 21:17 · JFK 00:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.