见字如面,大家好,我是小斐,这篇主要针对PowerDNS的管理做简单介绍。 背景 PowerDNS日常管理使用命令行不太便捷 ,而且在公司内部, 可能还需要给其他运维或者研发人员开通添加域名管理权限 ,在此我推荐一套针对PDNS可视化UI管理工具--PowerDNS-Admin。 可以结合 SAML / LDAP / Active Directory 用户认证 ,可以解决多人登录该域名管理系统的权限问题。 部署 前文提到安装PowerDNS后,域名区域数据不在使用 bind文件格式 存储,而直接使用后端连接 MySQL数据库。 已配置好相关数据库表格式,和数据库用户,在这在此示例下: # PowerDNS-Admin的数据库 不能使用PowerDNS的数据库 必须分开 # 到前文所说的主库中root登录mysql数据库 创建 powerdnsadmin 数据库 CREATE DATABASE `powerdnsadmin` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL PRIVILEGES ON `powerdnsadmin`.* TO "pdnsadminuser"@"%" IDENTIFIED BY "PowerDNS@Admin987"; FLUSH PRIVILEGES;安装 安装方式:docker和docker-compose或本地化部署 系统:Ubuntu 22.04.1 LTS 本地化部署说明: # 安装构建 python 库所需的包 sudo apt install -y python3-dev git libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev pkg-config apt-transport-https virtualenv build-essential curl # 安装 Node.js curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt-get install -y nodejs # 安装 yarn 构建依赖文件 sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt update && sudo apt install yarn # 检查源代码并创建 virtualenv 源代码放在/opt/web/powerdns-admin/目录下 git clone https://github.com/PowerDNS-Admin/PowerDNS-Admin.git /opt/web/powerdns-admin # 安装virtualenv包 创建virtualenv apt install python3.10-venv # 创建虚拟环境目录 venv虚拟环境目录名称 可自定义 python3 -mvenv ./venv 或者 virtualenv -p python3 venv # 激活虚拟环境 source ./venv/bin/activate pip install --upgrade pip # 数据库依赖包安装 apt install libmysqlclient-dev pip3 install mysqlclient==2.0.1 # 安装python项目依赖包 pip install -r requirements.txt # 配置文件位置 cp /opt/web/powerdns-admin/configs/development.py /opt/web/powerdns-admin/configs/production.py # 修改配置文件 在下面说明 vim /opt/web/powerdns-admin/configs/production.py 配置环境启动文件: vim /opt/web/powerdns-admin/configs/production.py import os import urllib.parse basedir = os.path.abspath(os.path.dirname(__file__)) ### BASIC APP CONFIG ### SALT 随机加密字符串 SALT = "$2b$12$yLUMTIfl21FKJQpTkRQXCu" ### 安全密钥 可以用Python生成 python -c "import secrets; print(secrets.token_hex(16))" SECRET_KEY = "3f17176a67336b4112b524295cc0e48a" ### 监听地址 BIND_ADDRESS = "0.0.0.0" ### 监听端口 PORT = 9191 OFFLINE_MODE = False FILESYSTEM_SESSIONS_ENABLED = False SESSION_COOKIE_SAMESITE = "Lax" CSRF_COOKIE_HTTPONLY = True ### DATABASE CONFIG ### 配置MySQL数据库的基本信息 SQLA_DB_USER = "pdnsadminuser" SQLA_DB_PASSWORD = "PowerDNS@Admin987" SQLA_DB_HOST = "192.168.10.120" SQLA_DB_NAME = "powerdnsadmin" SQLALCHEMY_TRACK_MODIFICATIONS = True ### DATABASE - MySQL ### 启动MySQL数据库 SQLALCHEMY_DATABASE_URI = "mysql://{}:{}@{}/{}".format( urllib.parse.quote_plus(SQLA_DB_USER), urllib.parse.quote_plus(SQLA_DB_PASSWORD), SQLA_DB_HOST, SQLA_DB_NAME ) ### DATABASE - SQLite ### SQLite数据库注释关闭 #SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "pdns.db") SAML_ENABLED = False SAML_ASSERTION_ENCRYPTED = True 手动启动: # 切换到目录 /opt/web/powerdns-admin/ source ./venv/bin/activate # 导入启动配置文件 export FLASK_CONF=../configs/production.py # 数据库表格式生成 export FLASK_APP=powerdnsadmin/__init__.py flask db upgrade # yarn 包管理器安裝一些 JavaScript 依赖项以及为 PowerDNS-Admin 生成静态文件 yarn install --pure-lockfile flask assets build # 前台运行 ./run.py # 退出虚拟环境 deactivate 到此已把环境准备好,包括相关数据库配置和应用程序配置,可以直接启动。 但是在实际生成环境中,前面肯定还是需要Web服务器,比如nginx,但是Python应用程序如何和Web服务器进行交互呢,故需要一套WSGI容器链接Web服务器和Python应用程序,如下图: 这里将采用Nginx+Gunicorn,由于PowerDNS-Admin是基于Flask框架实现的,同时把应用服务器的启停注册为systemd管理。 # flask virtualenv 中安装了 gunicorn 切换到venv环境下 cd /opt/web/powerdns-admin/ source ./venv/bin/activate pip install gunicorn 配置系统服务: # 创建运行服务的系统用户和组 sudo groupadd powerdnsadmin # --system 创建一个没有登录shell和密码的用户,适用于运行系统服务 sudo useradd --system -g powerdnsadmin powerdnsadmin # 授权新用户应用程序目录权限 chown -R powerdnsadmin:powerdnsadmin /opt/web/powerdns-admin # 创建系统用户 sudo vim /etc/systemd/system/powerdns-admin.service [Unit] Description=PowerDNS-Admin Requires=powerdns-admin.socket After=network.target [Service] PIDFile=/run/powerdns-admin/pid User=powerdnsadmin Group=powerdnsadmin WorkingDirectory=/opt/web/powerdns-admin Environment="FLASK_CONF=../configs/production.py" ExecStartPre=+mkdir -p /run/powerdns-admin/ ExecStartPre=+chown pdns:pdns -R /run/powerdns-admin/ ExecStart=/opt/web/powerdns-admin/venv/bin/gunicorn --pid /run/powerdns-admin/pid --bind unix:/run/powerdns-admin/socket "powerdnsadmin:create_app()" ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target 环境说明: Environment="FLASK_CONF=../configs/production.py" ,这里是基于Python的运行环境venv;由于实际代码在 /opt/web/powerdns-admin/powerdns-admin/ 中,故启动配置文件写相对路径放置在/opt/web/powerdns-admin/configs中,故配置文件环境变量设置相对路径: ../configs/production.py 新建套接字单元配置: powerdns-admin.socket # 套接字单元配置:powerdns-admin.socket # 以 ".socket" 为后缀的单元文件, 封装了一个用于进程间通信的套接字(socket)或管道(FIFO), 以支持基于套接字的启动。 sudo vim /etc/systemd/system/powerdns-admin.socket [Unit] Description=PowerDNS-Admin socket [Socket] ListenStream=/run/powerdns-admin/socket [Install] WantedBy=sockets.target 新建配置文件:sudo vim /etc/tmpfiles.d/powerdns-admin.conf # powerdns-admin.conf 必须新建 /run/powerdns-admin/ 自动创建并授权正确权限 sudo vim /etc/tmpfiles.d/powerdns-admin.conf d /run/powerdns-admin 0755 powerdnsadmin powerdnsadmin - 启动: sudo systemctl daemon-reload sudo systemctl start powerdns-admin.socket sudo systemctl enable powerdns-admin.socket # 启动服务 sudo systemctl start powerdns-admin.service sudo systemctl enable powerdns-admin.service反向代理配置 安装nginx # 安装nginx apt install nginx # 配置 80端口 vim /etc/nginx/conf.d/pdns.conf server { listen *:80; server_name 192.168.10.200; index index.html index.htm; access_log /var/log/nginx/powerdns-admin.local.access.log combined; error_log /var/log/nginx/error_powerdnsadmin.log error; client_max_body_size 10m; client_body_buffer_size 128k; proxy_redirect off; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffers 32 4k; proxy_buffer_size 8k; proxy_set_header Host $http_host; proxy_set_header X-Scheme $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_headers_hash_bucket_size 64; location ~ ^/static/ { include /etc/nginx/mime.types; root /opt/web/powerdns-admin/powerdnsadmin; location ~* .(jpg|jpeg|png|gif)$ { expires 365d; } location ~* ^.+.(css|js)$ { expires 7d; } } location / { proxy_pass http://unix:/run/powerdns-admin/socket; proxy_read_timeout 120; proxy_connect_timeout 120; proxy_redirect off; } } 如果需要443域名并证书加密访问: server { listen 80; server_name pdns.itkmi.net; return 301 https://$http_host$request_uri; } server { listen 443 ssl http2; server_name pdns.itkmi.net; index index.html index.htm; error_log /var/log/nginx/error_powerdnsadmin.log error; access_log off; ssl_certificate /etc/letsencrypt/live/pdns.hwdomain.io/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/pdns.hwdomain.io/privkey.pem; #ssl_dhparam path_to_your_dhparam.pem; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_session_cache shared:SSL:10m; client_max_body_size 10m; client_body_buffer_size 128k; proxy_redirect off; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffers 32 4k; proxy_buffer_size 8k; proxy_set_header Host $http_host; proxy_set_header X-Scheme $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_headers_hash_bucket_size 64; location ~ ^/static/ { include /etc/nginx/mime.types; root /opt/powerdns-admin/powerdnsadmin; location ~* .(jpg|jpeg|png|gif)$ { expires 365d; } location ~* ^.+.(css|js)$ { expires 7d; } } location ~ ^/upload/ { include /etc/nginx/mime.types; root /opt/powerdns-admin; location ~* .(jpg|jpeg|png|gif)$ { expires 365d; } location ~* ^.+.(css|js)$ { expires 7d; } } location / { proxy_pass http://unix:/run/powerdns-admin/socket; proxy_read_timeout 120; proxy_connect_timeout 120; proxy_redirect http:// $scheme://; } } 至此完成PowerDNS-Admin的搭建,打开PowerDNS-Admin服务: 先注册用户,第一个用户将处于管理员角色。 第一次登录时,将被重定向到设置页面以配置PDNS API信息。 我这里是80端口和IP访问打开的:http://192.168.10.200 单击:Create an account账户,创建新账户,这第一个账户就是默认管理员账户。 你现在应该获得 PowerDNS-Admin 仪表板。 PowerDNS-Admin 正在运行,但仍未连接到 PowerDNS 服务器。 要使用 PowerDNS-Admin 设置 PowerDNS 服务器,你必须将通过 PowerDNS 服务器配置的 API 密钥添加到 PowerDNS-Admin。 这里需要修改下 PowerDNS 服务器的配置文件: # 启用webserver webserver=yes # webserver监听地址 从127.0.0.1改为0.0.0.0 webserver-address=0.0.0.0 # 默认任意地址都可以访问 实际环境建议限制下 webserver-allow-from=0.0.0.0/0 添加域名: 到此就完成PowerDNS-Admin的安装和配置, 后续讲解下域名记录添加和解析相关问题。