Как заставить DNS-запрос по умолчанию работать в режиме TCP?

В Китае так называемый GFW часто загрязняет результаты DNS, такие как

$ dig @8.8.8.8 archive.org 

;; QUESTION SECTION:
;archive.org.           IN  A

;; ANSWER SECTION:
archive.org.        2662    IN  A   159.106.121.75

Вот 159.106.121.75фейковый IP. Мы должны использовать режим TCP для запроса DNS:

$ dig @8.8.8.8 +tcp archive.org

;; QUESTION SECTION:
;archive.org.           IN  A

;; ANSWER SECTION:
archive.org.        237 IN  A   207.241.224.2

Теперь мы получаем настоящий IP 207.241.224.2.

В System Preferences-> Networkкнопка Advanced...может открыть вкладку для настройки DNS. Однако я могу только добавить IP-адреса DNS-серверов, но не могу ничего сделать. Итак, мой вопрос: как я могу заставить DNS-запрос по умолчанию работать в режиме TCP?

PS : Я не хочу изменять /etc/hostsфайл, чтобы обойти эту проблему, так как это неудобно. Если есть какой-нибудь элегантный способ решить эту проблему, это сэкономит мне много времени :) Спасибо.

Ответы (1)

Насколько я знаю, невозможно заставить mDNSResponder использовать TCP вместо UDP.

Я нашел обходной путь, хотя. Описанный ниже метод использует локальный DNS-прокси ( dnschef ), принудительно использующий TCP для исходящих DNS-запросов.

  • Скачайте и разархивируйте dnschef-0.3 .
  • Скачайте и разархивируйте dnslib
  • Скачать и разархивировать IPy-0.76

  • cdв папку dnslib :

    cd ~/Downloads/paulc-dnslib-04713cc4a9df 
    
  • установить dnslib :

    sudo python ./setup.py install
    
  • cdв папку IPy :

    cd ~/Downloads/IPy-0.76 
    
  • установить IPy :

    sudo python ./setup.py install
    
  • Откройте «Системные настройки» -> «Сеть», замените ваш текущий DNS-сервер (например, 8.8.8.8/8.8.8.4) на локальный с IP-адресом 127.0.0.1 и примените изменения.

  • cdв папку dnschef и запустите его:

    cd ~/Downloads/dnschef-0.3 
    sudo ./dnschef.py --nameservers 8.8.8.8#53#tcp
    

Если последняя команда слишком хлопотная или некрасивая (ну, это некрасиво, потому что вам нужно открыть Terminal.app и запустить DNS-прокси), вы можете переместить dnschef.py и .ini на другой путь и создать демон запуска для запустить DNS-прокси при загрузке.

Пример:

  • sudo mkdir /usr/local/python
  • sudo cp ~/Downloads/dnschef-0.3/dns* /usr/local/python/
  • sudo rm /usr/local/python/dnschef.exe
  • sudo touch /Library/LaunchDaemon/local.dnschef.plist
  • скопируйте и вставьте следующий контент во вновь созданный файл с помощью соответствующего редактора
    (например sudo nano /Library/LaunchDaemon/local.dnschef.plist):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Label</key>
        <string>local.dnschef</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/python/dnschef.py</string>
            <string>--nameservers</string>
            <string>8.8.8.8#53#tcp</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
    </plist>
    
  • Загрузите файл сsudo launchctl load -w /Library/LaunchDaemons/local.dnschef.plist

    Все создаваемые файлы и папки должны принадлежать пользователю root:wheel.

Я не проверял это, но я уверен, что вам понадобятся кавычки 8.8.8.8#53#tcp(в интерактивной начальной версии; файл .plist и так выглядит нормально).
@GordonDavisson Я проверил это, и кавычки (например, «8.8.8.8#53#tcp») прерывают демон запуска. Команда sudo ./dnschef.py --nameservers 8.8.8.8#53#tcpработает.
Верно. Кавычки необходимы в интерактивном режиме, чтобы оболочка не интерпретировала #их как маркер комментария; launchd не использует оболочку, поэтому кавычки там не нужны (и, как вы говорите, сломают ее, потому что нет оболочки для их удаления).
Спасибо за подробный ответ. Еще не пробовал, но я полностью уверен, что это работает :D
Обновленная ссылка для dnschef: github.com/iphelix/dnschef