---
# System prepended metadata

title: 反向proxy for DNS
tags: [proxy, Centos, DNS, Linux]

---

# Centos 7 install Nginx to DNS proxy
## 一.安裝元件。
### 1.安裝拓展套件庫
```
yum -y install epel-release
```
![snipaste20240119_111121](https://hackmd.io/_uploads/Hkov_PDFa.jpg)

### 2.安裝Nginx程式
```
yum install nginx -y
```
![snipaste20240119_111244](https://hackmd.io/_uploads/HJ96_wDYT.jpg)
![snipaste20240119_111444](https://hackmd.io/_uploads/r1w4KPvF6.jpg)

### 3.安裝STREAM模組
```
yum install nginx-mod-stream -y
```
![snipaste20240119_134020](https://hackmd.io/_uploads/B1hUoKPYT.jpg)

### 4.啟動 Nginx 及設定開機自動啟動
```
systemctl start nginx
systemctl enable nginx
```
![snipaste20240119_112208](https://hackmd.io/_uploads/BJGgoPwt6.jpg)

---

## 二.設定Nginx
### 1.設定Nginx設定檔
#### vim /etc/nginx/nginx.conf
在最下方加入
```
include /etc/nginx/conf.d/*.stream;
```
![snipaste20240119_140426](https://hackmd.io/_uploads/H1B--5vta.jpg)

### 2.設定dns.stream檔
##### vim /etc/nginx/conf.d/dns.stream
輸入以下指令，設定UDP的proxy。
```
stream {
        upstream DNS    {
                server "您的DNS server IP":53;
        }
        server {
                listen 53 udp;
                proxy_pass DNS;
                proxy_timeout 1s;
                proxy_responses 1;
        }
}

```
![snipaste20240119_141459](https://hackmd.io/_uploads/HJOO7qwFT.jpg)

### 3.測試conf有無問題
```
nginx -t
```
![snipaste20240119_141636](https://hackmd.io/_uploads/HJBAX5wYa.jpg)

### 4.重啟服務
```
nginx -s reload
```

---

## 三.防火牆設定
方式1:
```
firewall-cmd --add-port=53/tcp --permanent
firewall-cmd --add-port=53/udp --permanent
firewall-cmd --reload
```
![snipaste20240119_142034](https://hackmd.io/_uploads/ryH649vtp.jpg)

方式2:
```
firewall-cmd --permanent --zone public --add-service dns 
firewall-cmd --reload
```
![image](https://hackmd.io/_uploads/B1ZTcjlqT.png)

---

## 四.錯誤排除
### 出現 nginx: [emerg] bind() to 0.0.0.0:53 failed (13: Permission denied)
原因為無權限偵聽53port，將SELinux關閉即可。
```
# 確認 SELinux 是否已 disabled，若否則更改 SELinux 設定並重啟系統
if [ -z "`cat /etc/selinux/config | grep \"SELINUX=disabled\"`" ]
then
        sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
		sed -i -e 's/SELINUXTYPE=targeted/#SELINUXTYPE=targeted/' /etc/selinux/config
        reboot
fi
```
![snipaste20240119_150605](https://hackmd.io/_uploads/SJDOyovt6.jpg)

---

## 五.測試結果
實測遇到cname紀錄時，因不會對其他外部DNS查找，無法正常指向，為正常現象(下圖以CNAME為例)；由於實際上client端的DNS也不會設定為此SERVER，因此client會透過網卡所設定的DNS，將IP解析出來。
![snipaste20240119_160936](https://hackmd.io/_uploads/r1ZI0swK6.jpg)

## 六.連線限制
vim /etc/nginx/conf.d/dns.stream，加入下面所述的設定。
```
 limit_conn_zone $binary_remote_addr zone=addr:10m;
 server {

        ...

        limit_conn           addr 1;
        limit_conn_log_level error;
    }
```
> limit_conn add 1 :每個IP只允許一個連線，超過時會關閉連線。
> limit_conn_log_level error : 關閉連線時LOG的等級。
> limit_conn_zone $binary_remote_addr zone=addr:10m :以來源IP分，最多允許10m的連線(1 MB 區域可以保存大約 32,000 個 32 位元組狀態或大約 16,000 個 64 位元組狀態)如果超過，將關閉連線
> $binary_remote_addr : 此變數表示為client的IP

![image](https://hackmd.io/_uploads/Hk953AecT.png)

## 七.備援SERVER
```
server backup1.example.com:12345   backup;
server backup2.example.com:12345   backup;
```
![image](https://hackmd.io/_uploads/Hy6l6Ag9T.png)

---

###### 參考資料:
https://www.cnblogs.com/yzgblogs/p/15235045.html
https://www.ltsplus.com/linux/nginx-config-reverse-proxy
https://snippetinfo.net/media/2463
https://cloud.tencent.com/developer/article/1449427
https://blog.csdn.net/qq_43038960/article/details/134918424
https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html
https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html
https://nginx.org/en/#generic_proxy_server_features
https://cloud.tencent.com/developer/article/2013168
https://www.uuu.com.tw/Public/content/article/23/20231225.htm
https://cloud.tencent.com/developer/article/2013168