Loading

快速运维 - NGINX

NGINX 篇

日志统计分析常用命令

统计IP访问量

awk '{print $1}' access.log | sort -n | uniq | wc -l

查看某一时间段的IP访问量(4-5点)

grep "07/Apr/2017:0[4-5]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l

查看访问最频繁的前100个IP

awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100

查看访问100次以上的IP

awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn

查询某个IP的详细访问情况,按访问频率排序

grep '104.217.108.66' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100

查看访问最频的页面(TOP100)

awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 100

查看访问最频的页面([排除php页面】(TOP100)

grep -v ".php" access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100

查看页面访问次数超过100次的页面

cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less

查看最近1000条记录,访问量最高的页面

tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less

统计每秒的请求数,top100的时间点(精确到秒)

awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100

统计每分钟的请求数,top100的时间点(精确到分钟)

awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100

每小时请求量统计

统计每小时的请求数,top100的时间点(精确到小时)

awk '{print $4}' access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100

性能分析

在nginx log中最后一个字段加入$request_time

列出传输时间超过 3 秒的页面,显示前20条

cat access.log|awk '($NF > 3){print $7}'|sort -n|uniq -c|sort -nr|head -20

列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条

cat access.log|awk '($NF > 1 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100

查看当前TCP连接数

netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l

用tcpdump嗅探80端口的访问看看谁最高

tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr

允许所有跨域

location / {
    # 允许所有来源跨域
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

    if ($request_method = 'OPTIONS') {
        # 预检请求的响应
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

自动判断跨域

根据域名后缀添加OPTIONS预检头

map $http_referer $cors_list {
    default  "null";
    "~^(https?:\/\/)?.*\.gov.cn\/?$" $http_referer;
    "~^(https?:\/\/.*\.gd\.cn\/?)$" $1;
}
map $http_origin $cors_list{
    default  "";
    "~^(https?:\/\/.*\.gov\.cn\/?)$" $1;
    "~^(https?:\/\/.*\.gd\.cn\/?)$" $1;
}
if ($request_method ~* ^(OPTIONS)$) {
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
}

多层NGINX HTTPS跳转异常

proxy_redirect http:// https://;

配置空格缩进和禁止自动缩进

echo "set tabstop=4" >> ~/.vimrc
echo "set shiftwidth=4" >> ~/.vimrc
echo "set expandtab" >> ~/.vimrc
echo "set noautoindent" >> ~/.vimrc
echo "set nosmartindent" >> ~/.vimrc
echo "set indentexpr=" >> ~/.vimrc

禁止使用IP访问配置

    server {
        listen 80;
        listen [::]:80;
        listen 443 ssl ;
        listen [::]:443 ssl ;

        access_log off;	

        # 这个是如果是IP的HOST的话,禁止访问
        server_name "~^(?:25[0-5]|2[0-4]\d|[0-1]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d{1,2})){3}$";
        #server_name "~^(\[)?([[:xdigit:]]{1,4}(?::[[:xdigit:]]{1,4}){7}|::|:(?::[[:xdigit:]]{1,4}){1,6}|[[:xdigit:]]{1,4}:(?::[[:xdigit:]]{1,4}){1,5}|(?:[[:xdigit:]]{1,4}:){2}(?::[[:xdigit:]]{1,4}){1,4}|(?:[[:xdigit:]]{1,4}:){3}(?::[[:xdigit:]]{1,4}){1,3}|(?:[[:xdigit:]]{1,4}:){4}(?::[[:xdigit:]]{1,4}){1,2}|(?:[[:xdigit:]]{1,4}:){5}:[[:xdigit:]]{1,4}|(?:[[:xdigit:]]{1,4}:){1,6}:)(\])?(\/)?$";
        #server_name _;
        
        ssl_reject_handshake on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_stapling off;
        ssl_certificate ../ssl/localhost-cert.pem;
        ssl_certificate_key ../ssl/localhost-key.pem;

        return 403;
    }

自适应网站域名配置

    server {

        server_name  "~^(?<domain>.+)$";
        #server_name_in_redirect on;
         
        listen       80 reuseport;
        listen       [::]:80 reuseport;

        listen	 443 ssl http2 reuseport;
        listen	 [::]:443 ssl http2 reuseport;
        
        #只有状态码为2XX和3XX才记录日志 变量在map中定义   
        access_log logs/$domain.log main if=$loggable;
        #相反的,记录非法访问
        access_log logs/hack-access.log main if=$unloggable;

        if ($request_method !~ ^(GET|POST|HEAD|OPTIONS)$) {
            return '405';
        }

    
        ssl_certificate ../ssl/$ssl_server_name.pem;
        ssl_certificate_key ../ssl/$ssl_server_name.key;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 1d;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers on;
        ssl_dhparam   ../ssl/dhparam.pem;
        ssl_stapling on;
        ssl_stapling_verify on;


        gzip on;
        gzip_proxied any;
        gzip_vary on;
        gzip_min_length 60k;
        gzip_buffers 4 16k;
        gzip_comp_level 5;
        gzip_types      text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
        gzip_disable "MSIE [1-6]\.";

        location /echo {
	    if ( $request_method !~* ^(GET|POST)$ ) { return 405; }
            default_type  text/html;
            echo '<h1>nginx test page</h1>';
            echo '<h2>$host</h2>';
            echo '<h3>return info:</h3>';
            echo '<ul>';
            echo '<li>uri: $uri || request_uri: $request_uri </br></li>';
            echo '<li>args: $args</li>';
            echo '<li>scheme: $scheme || server_protocol: $server_protocol</br></li>';
            echo '<li>basename: $basename</br></li>';
            echo '<li>regex: $domain<br></li>';
            echo '<li>ssl_server_name: $ssl_server_name</br></li>';
            echo '<li>cors_list: $cors_list</br></li>';
            echo '<hr>';
            echo '<li>Referer: $http_referer</br></li>';
            echo '<li>Origin: $http_origin</br></li>';
            echo '<li>remote_addr: $remote_addr </br></li>';
            echo '<li>From: $http_x_forwarded_for </br></li>';
            echo '<li>proxy_add_forwarded: $proxy_add_forwarded </br></li>';
            echo '<li>Pod: $upstream_addr </br></li>';
            echo '<li>UA: $http_user_agent </br></li>';
            echo '<hr>';
            echo '<li> <$geoip2_data_country_name$geoip2_data_city_subdivisions$geoip2_data_city_name>[$request_method ($status) ] request_time: $request_time - "$time_local"</br></li>';
            echo '</ul>';            
        }
    }

常用本体配置

user  root;
worker_processes  auto;
worker_rlimit_nofile 65535;

#error_log  /dev/stdout;
error_log  logs/error.log;

pid        /run/nginx.pid;


events {
    #use epoll;
    multi_accept       on;
    worker_connections  65535;
}

http {
    include       mime.types;
    default_type text/plain;

    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 buffer=32k flush=1m;
    open_log_file_cache max=1000 inactive=1m valid=3m min_uses=2;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Real-IP;
    real_ip_recursive on;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    charset utf-8;
    keepalive_timeout  65;
}

nginx 变量

$args                    #请求中的参数值
$query_string            #同 $args
$arg_NAME                #GET请求中NAME的值
$is_args                 #如果请求中有参数,值为"?",否则为空字符串
$uri                     #请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如"/foo/bar.html"。
$document_uri            #同 $uri
$document_root           #当前请求的文档根目录或别名
$host                    #优先级:HTTP请求行的主机名>"HOST"请求头字段>符合请求的服务器名.请求中的主机头字段,如果请求中的主机头不可用,则为服务器处理请求的服务器名称
$hostname                #主机名
$https                   #如果开启了SSL安全模式,值为"on",否则为空字符串。
$binary_remote_addr      #客户端地址的二进制形式,固定长度为4个字节
$body_bytes_sent         #传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的"%B"参数保持兼容
$bytes_sent              #传输给客户端的字节数
$connection              #TCP连接的序列号
$connection_requests     #TCP连接当前的请求数量
$content_length          #"Content-Length" 请求头字段
$content_type            #"Content-Type" 请求头字段
$cookie_name             #cookie名称
$limit_rate              #用于设置响应的速度限制
$msec                    #当前的Unix时间戳
$nginx_version           #nginx版本
$pid                     #工作进程的PID
$pipe                    #如果请求来自管道通信,值为"p",否则为"."
$proxy_protocol_addr     #获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串
$realpath_root           #当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径
$remote_addr             #客户端地址
$remote_port             #客户端端口
$remote_user             #用于HTTP基础认证服务的用户名
$request                 #代表客户端的请求地址
$request_body            #客户端的请求主体:此变量可在location中使用,将请求主体通过proxy_pass,fastcgi_pass,uwsgi_pass和scgi_pass传递给下一级的代理服务器
$request_body_file       #将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传 递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off,uwsgi_pass_request_body off,or scgi_pass_request_body off
$request_completion      #如果请求成功,值为"OK",如果请求未完成或者请求不是一个范围请求的最后一部分,则为空
$request_filename        #当前连接请求的文件路径,由root或alias指令与URI请求生成
$request_length          #请求的长度 (包括请求的地址,http请求头和请求主体)
$request_method          #HTTP请求方法,通常为"GET"或"POST"
$request_time            #处理客户端请求使用的时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$request_uri             #这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:"/cnphp/test.php?arg=freemouse"
$scheme                  #请求使用的Web协议,"http" 或 "https"
$server_addr             #服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中
$server_name             #服务器名
$server_port             #服务器端口
$server_protocol         #服务器的HTTP版本,通常为 "HTTP/1.0" 或 "HTTP/1.1"
$status                  #HTTP响应代码
$time_iso8601            #服务器时间的ISO 8610格式
$time_local              #服务器时间(LOG Format 格式)
$cookie_NAME             #客户端请求Header头中的cookie变量,前缀"$cookie_"加上cookie名称的变量,该变量的值即为cookie名称的值
$http_NAME               #匹配任意请求头字段;变量名中的后半部分NAME可以替换成任意请求头字段,如在配置文件中需要获取http请求头:"Accept-Language",$http_accept_language即可
$http_cookie        #请求的所有cookie
$http_host               #请求地址,即浏览器中你输入的地址(IP或域名)
$http_referer            #url跳转来源,用来记录从那个页面链接访问过来的
$http_user_agent         #用户终端浏览器等信息
$http_x_forwarded_for    #客户端的IP和代理服务器的IP,以逗号隔开;可伪造
$http_x_forwarded_proto  #请求的协议
$sent_http_NAME          #可以设置任意http响应头字段;变量名中的后半部分NAME可以替换成任意响应头字段,如需要设置响应头Content-length,$sent_http_content_length即可
$sent_http_cache_control
$sent_http_connection
$sent_http_content_type
$sent_http_keep_alive
$sent_http_last_modified
$sent_http_location

nginx 上的安全规则

# 接管HTTP状态码>=300的响应,而不是总由客户端响应 
proxy_intercept_errors on;

# 跨站脚本攻击的偏执行正则表达式
if ($request_uri ~ "((\\%3C)|<)[^\\n]+((\\%3E)|>)/)" { return 403; }
# 删除SQL元字符的正则表达式
if ($request_uri ~ "(\\%27)|(\\')|(\\-\\-)|(\\%23)|(#)") { return 403; }
# 简单跨站脚本攻击的正则表达式
if ($request_uri ~ "((\\%3C)|<)((\\%2F)|\\/)*[a-z0-9\\%]+((\\%3E)|>)") { return 403; }
# 传统SQL注入攻击的正则表达式
if ($request_uri ~ "\\w*((\\%27)|(\\'))((\\%6F)|o|(\\%4F))((\\%72)|r|(\\%52))") { return 403; }
# 删除有UNION关键字的SQL注入攻击的正则表达式
if ($request_uri ~ "((\\%27)|(\\'))union/ix (\\%27)|(\\')") { return 403; }
# 在MS SQL服务器上检测SQL注入攻击的正则表达式
if ($request_uri ~ "exec(\\s|\\+)+(s|x)p\\w+") { return 403; }

日志轮替和校验

使用logrotate来进行日志分割并校验

创建md5s文件,存放日志md5值,/TRS/APP/nginx/logs/md5s.txt,并且设定日志文件不允许删除、覆写,只允许追加

touch     /TRS/APP/nginx/logs/md5s.txt
chattr +a /TRS/APP/nginx/logs/md5s.txt

定义日志轮替配置文件 /etc/logrotate.d/nginx

/TRS/APP/nginx/logs/*.log {
    olddir /TRS/APP/nginx/logs/history
    daily
    create
    copytruncate
    rotate 360
    compress
    notifempty
    dateext
    sharedscripts
    missingok
    postrotate
        nginx -s reopen
    endscript
    lastaction
        find /TRS/APP/nginx/logs/history -type f -mtime -1 -exec md5sum {} >> /TRS/APP/nginx/logs/md5s.txt \;
    endscript
    su root root
}
  • olddir 日志备份的目录
  • postrotate 日志轮替完后进行的操作
  • lastaction 所有日志轮替完后进行的脚本

daily

表示每天整理一次

rotate

表示保留×天的备份文件

dateext

文件后缀是日期格式,也就是切割后文件是:xxx.log-20171205.gz

copytruncate

用于还在打开中的日志文件,把当前日志备份并截断
创建副本后将原始日志文件截断到位,而不是移动旧日志文件并选择创建新日志文件。当某些程序无法被告知关闭其日志文件时,可以使用它,因此可能会永远继续写入(附加)之前的日志文件。请注意,在复制文件和截断文件之间有一个非常小的时间段,因此一些日志数据可能会丢失。当使用此选项时,创建选项将不起作用,因为旧的日志文件保持不变。

compress

通过gzip压缩转储以后的日志

missingok

如果日志不存在则忽略该警告信息

notifempty

如果是空文件的话,不转储

sharedscripts

此标志意味着添加到配置中的任何脚本每次运行仅运行一次,而不是每个文件。由于此配置将匹配两个日志文件

prerotate

轮替前的指令

postrotate

轮替后的指令,最通常的作用是让应用重启,以便切换到新的日志文件, 在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。在这种情况下,rsyslogd 进程将立即再次读取其配置并继续运行

endscript

结束以上的指令

操作完成后,每天3点,系统会分割nginx日志文件,并将日志文件的备份文件追加到指定文件中。日后只需要校对MD5值,便可以知道日志有没有被篡改,从日志中排查是否有被攻击的。

反向代理推荐配置

需要补充变量,否则代理配置会出错

程序配置

map $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}
map $remote_addr $proxy_forwarded_elem {
    # IPv4 addresses can be sent as-is
    ~^[0-9.]+$        "for=$remote_addr";
    # IPv6 addresses need to be bracketed and quoted
    ~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
    # Unix domain socket names cannot be represented in RFC 7239 syntax
    default           "for=unknown";
}
map $http_forwarded $proxy_add_forwarded {
    # If the incoming Forwarded header is syntactically valid, append to it
    "~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
    # Otherwise, replace it
    default "$proxy_forwarded_elem";
}

自定义配置

proxy_pass https://zmhd.jiujiang.gov.cn/IGI;
proxy_buffering off;
proxy_redirect off;
proxy_read_timeout 86400;
proxy_connect_timeout 120;
proxy_http_version 1.1;
proxy_ssl_server_name on;
proxy_ssl_verify off;
proxy_set_header remote_addr $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host:$server_port;
proxy_next_upstream error timeout http_500;
proxy_set_header Forwarded $proxy_add_forwarded;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host:$server_port;
proxy_set_header X-Forwarded-Port  $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root   html;
index  index.html index.htm;
client_max_body_size 200m;

自动只允许政府网站跨域/嵌套(拒绝模式)

Content-Security-Policy HTTP 响应头有一个 frame-ancestors 指令,支持这一指令的浏览器已经废弃了 X-Frame-Options 响应头。

意思是,X-Frame-Options应该只会被IE内核的浏览器识别。

在nginx.conf配置中添加如下代码

map $http_referer $can_be_iframe {
    default "DENY";
    "https://www.demo.gov.cn" "";
    "~.*\.gov\.cn$" "";
    "~^(https?:\/\/.*\.gov\.cn\/?)$" $1;
}
map $http_origin $cors_list{
    default  "";
    "~^(https?:\/\/.*\.gov\.cn\/?)$" $1;
}   

在对应的网站配置文件中添加

add_header X-Frame-Options $can_be_iframe always;
add_header Access-Control-Allow-Origin $cors_list always;

代码高亮

cp contrib/vim/ ~/.vim/ -r
echo 'au BufRead,BufNewFile */TRS/APP/nginx/* set ft=nginx' >> ~/.vim/ftdetect/nginx.vim

开启TLSv1.3 不成功

NGINX 默认的 TLS 协议总是会先遵守 default_server,因此需要默认配置段中开启该协议,例子如下

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;
    ssl_reject_handshake on;
    ssl_protocols TLSV1.2 TLSv1.3;
    ssl_stapling off;
    ssl_certificate /usr/share/doc/perl-IO-Socket-SSL-1.94/certs/server-cert.pem;
    ssl_certificate_key /usr/share/doc/perl-IO-Socket-SSL-1.94/certs/server-key.pem;
    return 400;
}

需要注意的是,server块中需要含有ssl_certificate和ssl_certificate_key证书,否则无法生效,

证书文件和密钥文件不需要有效,只要是合规的文件即可,如果没有,可以通过命令的方式安装

yum install -y perl-IO-Socket-SSL perl-File-ShareDir

安装完成后,证书在/usr/share/doc/perl-IO-Socket-SSL-1.94/certs/下

perl-IO-Socket-SSL-1.94可能是其他版本,目录可能不一致,需要根据实际情况修改即可。

成果效果

设置开机自启

推荐使用Systemd的模式进行管理,复制代码粘贴直接运行即可

sudo tee /lib/systemd/system/nginx.service <<'EOF'
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
ExecStartPre=/TRS/APP/nginx/sbin/nginx -t
ExecStart=/TRS/APP/nginx/sbin/nginx
ExecReload=/TRS/APP/nginx/sbin/nginx -s reload
ExecStop=/TRS/APP/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
posted @ 2023-10-12 15:28  p#ssw0rd  阅读(62)  评论(0编辑  收藏  举报