本文为翻译,并加上了自己的一些修改。
原文:https://facebookexperimental.github.io/doh-proxy/tutorials/nginx-dohhttpproxy-unbound-centos7.html
本文介绍在CentOS 7搭建DNS over HTTPS并使用Nginx作为前端的教程。
环境搭建
基础工具
我们在CentOS 7下需要安装几个包,以下操作均以root用户权限:
yum -y install git bind-utils certbot-nginx
其中git可选。bind-utils带dig工具,certbox-nginx是为了申请Let’s Encrypt的SSL证书才安装的。
Python 3.6
doh-proxy需要使用到python 3.6版本,所以需要额外安装。在CentOS 7下我们使用IUS的Repo:
yum -y install https://centos7.iuscommunity.org/ius-release.rpm yum -y install python36u python36u-pip python36u-devel
配置doh-proxy
使用pip安装:
pip3.6 install doh-proxy
如果想要尝鲜最新版,则需要安装git后输入
pip3.6 install git+https://github.com/facebookexperimental/doh-proxy.git
创建新用户
我们将会以一个新用户跑dns-proxy程序,所以需要创建它。
adduser -r doh-proxy \ -d /var/lib/doh-proxy \ -c 'DOH Proxy server' \ -s /sbin/nologin \ -U mkdir /var/lib/doh-proxy \ && chown doh-proxy: /var/lib/doh-proxy \ && chown 700 /var/lib/doh-proxy
创建systemd unit文件
cat </etc/systemd/system/doh-httpproxy\@.service [Unit] Description=DOH HTTP Proxy on %I After=syslog.target network.target Before=nginx.target [Service] Type=simple ExecStart=/bin/doh-httpproxy --upstream-resolver ::1 --level DEBUG --listen-address=::1 --port %I Restart=always User=doh-proxy Group=doh-proxy [Install] WantedBy=multi-user.target EOF systemctl daemon-reload
接下来我们要启动2个doh-httpproxy,分别监听在8080和8081口上。
for i in 8080 8081 do # We can't link on CentOS7 due to https://github.com/systemd/systemd/issues/3010 # ln -s /etc/systemd/system/doh-httpproxy\@.service \ cp /etc/systemd/system/doh-httpproxy\@.service \ /etc/systemd/system/doh-httpproxy\@${i}.service systemctl enable doh-httpproxy@${i} systemctl start doh-httpproxy@${i} done
dns-proxy配置完毕,但目前本地(上方upstream的::1
地址,是个本地地址,类似localhost)还没有一台DNS服务器,所以要在本地搭建一个。我们使用unbound。
设置unbound
安装unbound并监听127.0.0.1以及::1地址。
yum -y install unbound systemctl enable unbound systemctl start unbound
测试可通过以下命令
dig @::1 example.com
最后我们还有一步要做,设置Nginx与我们的doh-proxy对话
配置Nginx
安装Nginx
yum -y install nginx systemctl enable nginx systemctl start nginx
申请证书,你需要先设置一个域名然后把A(以及AAAA)记录指向你的机器,此机器需要能被外部访问到。本文用dns.example.com作为例子。
certbot --nginx -d dns.example.com
配置Nginx
找到/etc/nginx/nginx.conf
,找到以下内容:
listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot
替换成
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot listen 443 ssl http2; # managed by Certbot
添加规则,只允许GET/POST/HEAD的请求:
if ( $request_method !~ ^(GET|POST|HEAD)$ ) { return 501; }
找到下面这一块
location / { }
替换成
location /dns-query { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; proxy_buffering off; proxy_pass http://dohproxy_backend; }
添加上游,添加在server block的上面,像这样:
upstream dohproxy_backend { server [::1]:8080; server [::1]:8081; } server { server_name dns.example.com; # managed by Certbot
重启Nginx
systemctl restart nginx
如果开启了SELinux,则需要打通规则:
setsebool -P httpd_can_network_connect=true
测试
使用以下命令可以在5353口监听一个测试
doh-stub --listen-port 5353 --domain dns.example.com --remote-address ::1
用以下命令可以针对5353口进行dns query:
dig @::1 -p 5353 example.com
正常的话你应该能得到一个A记录了。