📓 Archive

  • Pricing
  • Chess
  • Syntax
  • NGINX

    FGJ: Create:2022/08/08 Update: (2026-01-19)

    • 简介 #

      • 1.介绍 #

        Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务,支持FastCGI,SSL,Virtual Host,URL Rewrite,Gzip等功能。

      • 2.功能 #

        • 反向代理
        • 负载均衡
        • 静态服务器
        • 邮箱服务器
      • 3.负载均衡方式 #

        nameexplainfeature
        轮询默认方式
        weight权重方式根据权重分发请求,权重大的分配到请求的概率大
        ip_haship 分配根据客户端请求的IP地址计算hash值, 根据hash值来分发请求, 同一个IP发起的请求, 会发转发到同一个服务器上
        url_hashurl 分配根据客户端请求url的hash值,来分发请求, 同一个url请求, 会发转发到同一个服务器上
        fair智能响应优先把请求分发给处理请求时间短的服务器
        least_conn最少连接哪个服务器当前处理的连接少, 请求优先转发到这台服务器
    • 编译安装 #

      Tip

      官方源码下载 1.16.11.26.2
      (可选)编译用的 openssl 源码库,主要为了支持 TLSv1.3

      Attention

      切换完依赖的 openssl 库后记得重启服务器,要不然可能会存在配置的 TLSv1.3 的功能,即使通过-s reload但依然死活不生效,误以为配置出问题了。

      # 安装依赖库
      sudo apt-get install libpcre3-dev libssl-dev
      
      wget -c https://nginx.org/download/nginx-1.16.1.tar.gz
      tar -zxf nginx-1.16.1.tar.gz
      cd nginx-1.16.1/
      
      # (可选)修改版本信息
      vim src/http/ngx_http_header_filter_module.c # 49-50
      # http v2,字符串使用一种叫 (HPACK's Huffman encoding) 的技术
      # https://stackoverflow.com/questions/35655448/how-does-this-code-result-in-the-string-nginx
      vim src/http/v2/ngx_http_v2_filter_module.c  # 151 ==> static const u_char nginx[9] = "\x88\xfc\x88\x22\x64\x2\x5c\xb4\x1b";
      # http v3,都快出来了...
      
      # (可选)指定编译用的 openssl 库
      wget -P /data/ https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1w/openssl-1.1.1w.tar.gz
      tar -zxf openssl-1.1.1w.tar.gz
      
      # 配置与编译
      # 编译选项:https://nginx.org/en/docs/configure.html
      ./configure --prefix=/usr/local/nginx/ --with-http_gzip_static_module --with-http_ssl_module --with-http_v2_module 
      	[--with-http_addition_module]
      	[--with-http_sub_module]
      	[--without-http_fastcgi_module] 
      	[--with-openssl=/data/openssl-1.1.1w] 
      	[--with-openssl-opt=enable-tls1_3]
      	[--with-debug]
      make
      objs/nginx -V
      
      # 安装
      make install
      
      # placeholder
      
    • 配置文件 #

      #=======================================
      # EXAMPLE and officia documents at (http://nginx.org/en/docs/)
      #=======================================
      #error_log  logs/error.log;
      #error_log  logs/error.log  notice;
      #error_log  logs/error.log  info;
      #access_log logs/brian.log main gzip buffer=128k flush=5s;
      #pid        logs/nginx.pid;
      
      # nginx compile
      # ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_gzip_static_module --with-http_ssl_module --with-http_v2_module
      
      # 1.=======================================
      # 在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/
      # 当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;
      # 如果没有/,则会把匹配的路径部分也给代理走.
      #
      # 2.=======================================
      # 代理重定向,如果关闭的话,重定向请求会直接映射到 http://tomcat/redirect/path
      # 开启后,重定向会通过nginx代理,项目内的重定向正常访问
      # proxy_redirect off;
      #
      # 3.=======================================
      # location /i/ {
      #	root /data/w3;
      # }
      # The /data/w3/i/top.gif file will be sent in response to the “/i/top.gif” request.
      #
      # location /i/ {
      #	alias /data/w3/images/;
      # }
      # on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.
      #
      # 4.=======================================
      # HTTP Strict Transport Security(HSTS) and NGINX (https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/)
      # 307 from temporary redirect to Internal Redirect configuration
      # add_header Strict-Transport-Security "max-age=172800; includeSubDomains" always;
      # (add_header) directive [There’s one important exception] 有一个例外,当且仅当自身level没有add_header 指令时,才会继承上一层的。不然得在当前块重新声明。
      # There could be several add_header directives. These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.
      # If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.
      #
      # 5.=======================================
      # location = /uri		精确匹配
      # location ^~ /uri 		开头匹配,可以理解为项目名,一旦匹配,停止其他(正则匹配)
      # location ~ /uri		区分大小写的正则匹配
      # location ~* /uri		不分区大小写的正则匹配
      # location /uri			不带修饰符的字符匹配,在正则匹配之后
      # location /			通用匹配,相当于else 中的内容,<==> switch 中的default
      # example1:
      # location = / {
      #     [ configuration A ]
      # }
      #
      # location / {
      #     [ configuration B ]
      # }
      #
      # location /documents/ {
      #     [ configuration C ]
      # }
      #
      # location ^~ /images/ {
      #     [ configuration D ]
      # }
      #
      # location ~* \.(gif|jpg|jpeg)$ {
      #     [ configuration E ]
      # }
      #
      # The “/” request will match configuration A,
      # the “/index.html” request will match configuration B,
      # the “/documents/document.html” request will match configuration C,
      # the “/images/1.gif” request will match configuration D,
      # and the “/documents/1.jpg” request will match configuration E.
      #
      # example2:
      # location ^~ /helloworld { #1
      #    	 return 601;
      # }
      # #location /helloworld { #2
      # #    	 return 602;
      # #}
      # location ~ /helloworld {
      # 		 return 603;
      # }
      # http://localhost/helloworld/test,返回601。如将#1注释,#2打开,浏览器输入http://localhost/helloworld/test,返回603。
      # 注:#1和#2不能同时打开,如同时打开,启动nginx会报nginx: [emerg] duplicate location “/helloworld”…,因为这两个都是普通字符串。
      # location /helloworld/test/ {
      #		return 601;
      # }
      # location /helloworld/ {
      #		return 602;
      # }
      # http://localhost/helloworld/test/a.html,返回601。http://localhost/helloworld/a.html,返回602
      # location ~ /helloworld {
      #		return 602;
      # }
      # location ~ /helloworld/test {
      #		return 603;
      # }
      # http://localhost/helloworld/test/a.html,返回602;将#2和#3调换顺序,http://localhost/helloworld/test/a.html,返回603
      #
      # 6.=======================================
      # include_ico:
      # location /favicon.ico {
      # 		root html;
      #	 	access_log off;
      #     	try_files $uri /;
      #     	expires 10d;
      # }
      #
      # 7.=======================================
      # include_robots:
      # location =/robots.txt {
      #      	default_type text/html;
      #      	add_header Content-Type "text/plain; charset=UTF-8";
      #      	return 200 "User-Agent: *\nDisallow: /";
      # }
      #
      # TODO 1,nginx configure robot.txt and favicon.ico
      # TODO 2,rewrite operation
      # TODO 3,hard link edit line
      #
      #=======================================
      
      #user  nobody;
      worker_processes  1;
      
      events {
      	worker_connections  1024;
      }
      
      http {
      	include       mime.types;
      	default_type  application/octet-stream;
      	#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
      	#                  '$status $body_bytes_sent "$http_referer" '
      	#                  '"$http_user_agent" "$http_x_forwarded_for"';
      	#access_log  logs/access.log  main;
      	sendfile        on;
      	#tcp_nopush     on;
      	keepalive_timeout  0;
      	# keepalive_timeout  65;
      	# 开启gzip
      	gzip  on;
      	# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
      	gzip_min_length 1k;
      	# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间。一般设置1和2
      	gzip_comp_level 2;
      	# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
      	gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png image/jpg;
      	# 是否在http header中添加Vary: Accept-Encoding,建议开启
      	gzip_vary on;
      	# 禁用IE 6 gzip
      	gzip_disable "MSIE [1-6]\.";
      	# 设置缓存路径并且使用一块最大100M的共享内存,用于硬盘上的文件索引,包括文件名和请求次数,每个文件在1天内若不活跃(无请求)则从硬盘上淘汰,硬盘缓存最大10G,满了则根据LRU算法自动清除缓存。
      	proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;
      	# 用于tomcat hot deploy (upload war)
      	client_max_body_size 200M;
      	# haha
      	# proxy_intercept_errors on;
      	# fastcgi_intercept_errors on;
      	# error_page 404 =200 /404.html;
      	#=======================================
      	# 隐藏返回头信息中nginx的版本号
      	server_tokens off;
      	# 隐藏server信息
      	# 需要重新编译nginx
      	# 进入解压出来的nginx源码目录
      	# vim src/http/ngx_http_header_filter_module.c # 49-50
      	# 修改以下两个值,后重新编译 example:Server: X-Web
      	# static char ngx_http_server_string[] = "Server:nginx";
      	# static cahr ngx_http_server_full_string[] = "Server:" NGINX_VER ;
      
      	upstream tomcat{
      		server 127.0.0.1:13380;
      	}
      
      	upstream activemq{
      		server 127.0.0.1:8161;
      	}
      
      	#=======================================
      	server {
      		listen       80;
      		server_name  example.com;
      
      		return 307 https://example.com/;
      		rewrite ^/(.*) https://example.com redirect;
      		# include ../html/include_robots;
      		# include ../html/include_ico;
      		#
      		# location / {
      		#     root   html;
      		#     index  index.html index.htm;
      		# }
      
      		# error_page 404 =200 /404.html;
      		# error_page   500 502 503 504  /50x.html;
      		# location = /50x.html {
      		#     root   html;
      		# }
      	}
      
      	#=======================================
      	server {
      		listen       80;
      		server_name  test.example.com;
      
      		location = / {
      			proxy_set_header Host $host;
      			proxy_set_header X-Real-IP $remote_addr;
      			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      			proxy_pass http://tomcat;
      			proxy_redirect off;
      			index index.html index.htm;
      			proxy_intercept_errors on;
      		}
      
      		# include ../html/include_robots;
      		# include ../html/include_ico;
      
      		error_page 404 =200  @notfound;
      		location @notfound {
      			default_type text/html;
      			# add_header Content-Type "text/plain; charset=UTF-8";
      			return 200 "<html><head><title>4004 Not Found</title></head><body><center><h1>4004 Not Found</h1></center><hr><center>nginx</center></body></html>";
      		}
      
      		error_page   500 502 503 504  /50x.html;
      		location = /50x.html {
      			root   html;
      		}
      	}
      
      	#=======================================
      	server {
      		listen       80;
      		server_name  mvn.example.com;
      
      		location / {
      			root   html;
      			index  index.html index.htm;
      		}
      
      		location ^~ /nexus/ {
      			proxy_set_header Host $host;
      			proxy_set_header X-Real-IP $remote_addr;
      			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      			proxy_pass http://127.0.0.1:10008;
      		}
      
      		# include ../html/include_robots;
      		# include ../html/include_ico;
      
      		error_page 404 =200 /404.html;
      		error_page   500 502 503 504  /50x.html;
      		location = /50x.html {
      			root   html;
      		}
      	}
      
      	#=======================================
      	server {
      		listen       80;
      		server_name  service.example.com;
      
      		location = /speed {
      			proxy_pass http://127.0.0.1:13330/speed/gui.html;
      			proxy_redirect off;
      		}
      
      		location / {
      			proxy_pass http://127.0.0.1:13330;
      			proxy_http_version 1.1;
      			proxy_read_timeout 360s;
      			proxy_redirect off;
      			proxy_set_header Upgrade $http_upgrade;
      			proxy_set_header Connection "upgrade";
      			proxy_set_header Host $host:$server_port;
      			proxy_set_header X-Real-IP $remote_addr;
      			proxy_set_header REMOTE-HOST $remote_addr;
      			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      		}
      
      		# include ../html/include_robots;
      		# include ../html/include_ico;
      
      		error_page 404 =200  @notfound;
      		location @notfound {
      			default_type text/html;
      			# add_header Content-Type "text/plain; charset=UTF-8";
      			return 200 "<html><head><title>4004 Not Found</title></head><body><center><h1>4004 Not Found</h1></center><hr><center>nginx</center></body></html>";
      		}
      
      		proxy_intercept_errors on;
      		error_page 404 =200 /404.html;
      		error_page   500 502 503 504  /50x.html;
      		location = /50x.html {
      			root   html;
      		}
      	}
      
      	# HTTPS server
      
      	#=======================================
      	server {
      		listen 443 ssl;
      		server_name www.example.com;
      		ssl_certificate 3_www.wtfu.site_bundle.crt;
      		ssl_certificate_key 3_www.wtfu.site.key;
      		ssl_session_timeout 5m;
      
      		# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      		# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
      		# ssl_prefer_server_ciphers on;
      
      		ssl_protocols TLSv1.2 TLSv1.3;
      		ssl_ciphers HIGH:!aNULL:!MD5:!RC4:!DHE:ECDHE-RSA-AES128-GCM-SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;
      		ssl_prefer_server_ciphers on;
      
      		# 启用 OCSP Stapling
      		ssl_stapling on;
      		ssl_stapling_verify on;
      		# 缓存 OCSP 响应的时间
      		resolver 8.8.8.8 8.8.4.4 valid=300s;  # 使用 Google DNS 解析器,设置缓存有效期为 5 分钟
      		resolver_timeout 10s;
      
      		# HSTS
      		# add_header Strict-Transport-Security "max-age=172800; includeSubDomains" always;
      
      		location / {
      			# HSTS
      			add_header Strict-Transport-Security "max-age=15552000" always; # includeSubDomains" always;
      			root html;
      			index index.html index.htm;
      		}
      
      		location = /_service_ {
      			default_type 'text/html; charset=UTF-8';
      			alias html/_service_.html;
      			auth_basic		'please input u&s';
      			auth_basic_user_file htpasswd;
      		}
      
      		location = /docker.html {
      			# add_header Content-Type "application/pdf";
      			add_header Content-Disposition 'inline; filename="docker.html"';
      			# add_header Cache-Control "no-cache";
      			keepalive_timeout 0;
      			root html;
      		}
      
      		location ^~ /blog {
      			alias html/docs/;
      			index index.html;
      			error_page 404  @notfounds;
      			gzip_comp_level 8;
      		}
      
      		location ^~ /resume/ {
      			# add_header Content-Type "application/pdf";
      			add_header Content-Disposition 'inline; filename="wtfu.pdf"';
      			# add_header Cache-Control "no-cache";
      			keepalive_timeout 0;
      			root html;
      		}
      
      		# include ../html/include_robots;
      		# include ../html/include_ico;
      
      		error_page 404 =200  @notfounds;
      		location @notfounds {
      			default_type text/html;
      			# add_header Content-Type "text/plain; charset=UTF-8";
      			return 200 "<html><head><title>4004 Not Found</title></head><body><center><h1>4004s Not Found</h1></center><hr><center>nginx</center></body></html>";
      		}
      
      		error_page   500 502 503 504  /50x.html;
      		location = /50x.html {
      			root   html;
      		}
      		# 开启缓存,关闭静态资源日志记录,节省服务器资源
      		# location ~* ^.+\.(css|js|ico|gif|jpg|jpeg|png)$ {
      			# log_not_found off;
      			# 关闭日志
      			# access_log off;
      			# 缓存时间7天
      			# expires 7d;
      			# 源服务器
      			# proxy_pass http://tomcat;
      			# 指定上面设置的缓存区域
      			# proxy_cache imgcache;
      			# 缓存过期管理
      			# proxy_cache_valid 200 302 1d;
      			# proxy_cache_valid 404 10m;
      			# proxy_cache_valid any 1h;
      			# proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
      		# }
      	}
      }
      
    • 应用 #

      • 1.使用http smart 协议搭建git 服务器 #

        • 安装fastcgi(fcgiwrap) #

          • mac brew install fcgiwrap

          • 其他源码安装(https://github.com/gnosek/fcgiwrap.git)

            centos提示 checking for FCGX_Init in -lfcgi… no configure: error: FastCGI library is missing

            需要安装 fcgi-devel :https://centos.pkgs.org/7/epel-x86_64/fcgi-devel-2.4.0-25.el7.x86_64.rpm.html

          • 启动fcgiwrap

            ./fcgiwrap -s help 查看-s选项 例 ./fcgiwrap -s tcp:127.0.0.1:12302./fcgiwrap -s unix:/tmp/cgi.sock

        • nginx配置 #

          默认包含fastcgi模块,只需要简单指令

          location /test/ {
          
          	#include /usr/local/etc/nginx/fastcgi_params;
          	# alias html; # @DOCUMENT_ROOT;
          
          	fastcgi_pass 127.0.0.1:12302; # fcgiwrap -s tcp:127.0.0.1:12302
          	fastcgi_connect_timeout 24h;
          	fastcgi_read_timeout 24h;
          	fastcgi_send_timeout 24h;
          	#fastcgi_param SCRIPT_FILENAME /usr/local/var/www/@fastcgi_script_name;
          	include fastcgi_params;
          
          	fastcgi_param SCRIPT_FILENAME /Users/stevenobelia/Desktop/gittest/abc.cgi;
          	fastcgi_param PATH_INFO $uri;
          }
          location ^~ /project {
          	auth_basic "Git Login";
          	auth_basic_user_file "/usr/local/etc/nginx/pass.db";
          
          	include fastcgi_params;
          
          	fastcgi_connect_timeout 24h;
          	fastcgi_read_timeout 24h;
          	fastcgi_send_timeout 24h;
          	fastcgi_pass	unix:/tmp/cgi.sock;
          	fastcgi_param CONTENT_LENGTH  $content_length;
          
          	fastcgi_param REQUEST_METHOD  $request_method;
          	fastcgi_param SCRIPT_FILENAME /Library/Developer/CommandLineTools/usr/libexec/git-core/git-http-backend;
          	fastcgi_param GIT_PROJECT_ROOT /Users/stevenobelia/Documents/_anft-backup/idea-project;
          	fastcgi_param PATH_INFO $uri;
          	fastcgi_param REMOTE_USER $remote_user;
          	fastcgi_param GIT_HTTP_EXPORT_ALL "";
          	#alias /Users/stevenobelia/Documents/_haohuo-backup/haohuo-data/project;
          	#autoindex on; #自动索引
          	#autoindex_exact_size off; #使得文件大小以MB,GB形式显示而非KB
          	#autoindex_localtime on; #使用本地时间
          	#index index.html index.htm;
          }
          
        • script-file[abc.cgi] #

          #!/bin/bash
          
          echo -e "Content-Type: text/html\n"
          echo "<html><head>"
          echo "</head><body>"
          echo "helloworld"
          echo "</body></html>"
          
        • reference #
    • 工具 #

      • 1.使用 acme.sh 自动化管理 ssl/tsl证书 #

        # 工具安装 acme.sh (https://github.com/acmesh-official/acme.sh)
        curl https://get.acme.sh | sh -s email=xhsgg12302@126.com
        
        # 工具升级
        acme.sh --upgrade
        # 工具保持自动升级
        acme.sh --upgrade --auto-upgrade
        
        # 工具配置
        # 颁发证书,使用 dnsapi 进行验证
        # 此处使用的是腾讯统一后的api 3.0[腾讯云 API 密钥]
        # 如果为dnspod的话,可以修改 [--dns dns_dp]
        # 需要注意的是如果使用的是 上面的dnsapi的话,需要DNSPod控制台(https://console.dnspod.cn/account/token/token)创建的token[DNSPod Token]而不是[腾讯云 API 密钥]。
        # 且导入的环境变量不通,参考(https://github.com/acmesh-official/acme.sh/wiki/dnsapi#2-dnspodcn-option)
        export Tencent_SecretId="xxxxx"
        export Tencent_SecretKey="xxxxx"
        
        # 证书 颁发
        	# 通配符域名可以和主域名共存。生成一张证书,多个域名。
        	acme.sh --issue --dns dns_tencent  -d wtfu.site -d *.wtfu.site
        
        # 证书 安装 
        # 建议不要手动复制,使用install-cert 命令安装后会记录相关参数在域名文件下的conf文件中。
        # 所以后续的操作,比如renew,cron等会使用到相关参数,以达到自动续期的功能。cron的话一般无需人工干预。且为 dnsapi模式。
        	acme.sh --install-cert -d wtfu.site --fullchain-file /usr/local/nginx/conf/certificate/multi/full_chain.pem  --key-file /usr/local/nginx/conf/certificate/multi/private.key --reloadcmd "/usr/local/nginx/sbin/nginx -s reload"
        
        # 证书 更新 (手动单个)
        	acme.sh --renew -d example.com [--force]
        # 证书 更新 (批量)
        	acme.sh --cron [--force]
        
        # 设置通知 (参见文档:https://github.com/acmesh-official/acme.sh/wiki/notify)
        	# 使用 smtp hook :https://github.com/acmesh-official/acme.sh/wiki/notify#12-set-notification-for-smtp
        	acme.sh --set-notify --notify-hook smtp --notify-source X_eli
        
        	export SMTP_FROM="xhsgg12302@126.com"  # just the email address (no display names)
        	export SMTP_TO="xhsgg12302@qq.com,xhsgg12302@gmail.com"  # just the email address, use commas between multiple emails
        	export SMTP_HOST="smtp.126.com"
        	export SMTP_SECURE="ssl"  # one of "none", "ssl" (implicit TLS, TLS Wrapper), "tls" (explicit TLS, STARTTLS)
        	export SMTP_PORT="465"
        	export SMTP_USERNAME="xhsgg12302@126.com"
        	export SMTP_PASSWORD="xxxxxx"
        	# export SMTP_BIN="/path/to/python_or_curl"
        	# export SMTP_TIMEOUT="30"  # seconds for SMTP operations to timeout, default 30
        
        # 吊销证书
        	# https://github.com/acmesh-official/acme.sh/wiki/revokecert
        	acme.sh --revoke  -d tech.wtfu.site   --revoke-reason 0
        
        # 算法选择
        	# https://github.com/acmesh-official/acme.sh?tab=readme-ov-file#10-issue-ecc-certificates
        	# 通过指定 --keylength [ec-256(default) | ec-384 | ec-521 | 2048 | 3072 | 4096] 等选择 ECC 或者 RSA,比如下面的选择为 2048 位的 RSA。
        	acme.sh --issue --dns dns_tencent  -d test.wtfu.site --keylength 2048
        	# 签发后查看证书中密匙交换用的算法信息如下:(rsaEncryption:RSA,id-ecPublicKey: EC/ECC)
        	openssl x509 -in /root/.acme.sh/test.wtfu.site/test.wtfu.site.cer --text --noout | grep -A 2 'Subject Public Key Info'
        
        # 厂商选择
        	# https://github.com/acmesh-official/acme.sh/wiki/Server
        	# 通过指定 --server [zerossl(default) | letsencrypt | ... ]
        	acme.sh --issue --server letsencrypt --dns dns_tencent  -d let.wtfu.site
        

    comments powered by Disqus