{"componentChunkName":"component---src-templates-docs-js","path":"/linux/linux-security","result":{"data":{"site":{"siteMetadata":{"title":"Front end learn note, HTML, CSS, JAVASCRIPT","docsLocation":"https://github.com/Boytobeaman/learnnote.site/tree/master/content"}},"mdx":{"fields":{"id":"4e7c4a6d-303e-54b8-bf6c-b349faf697a8","title":"linux 安全","slug":"/linux/linux-security"},"body":"var _excluded = [\"components\"];\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"linux 安全\",\n  \"metaTitle\": \"linux 安全，Linux 常用安全软件\",\n  \"metaDescription\": \"linux 安全，Linux 常用安全软件\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h3\", null, \"fail2ban \\u5B89\\u88C5\\u4E0E\\u914D\\u7F6E\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo apt update\\nsudo apt install fail2ban\\n\")), mdx(\"h4\", null, \"\\u57FA\\u672C\\u914D\\u7F6E\"), mdx(\"p\", null, \"fail2ban \\u7684\\u4E3B\\u8981\\u914D\\u7F6E\\u6587\\u4EF6\\u4F4D\\u4E8E\\uFF1A\"), mdx(\"p\", null, \"/etc/fail2ban/jail.conf - \\u4E3B\\u914D\\u7F6E\\u6587\\u4EF6\\uFF08\\u4E0D\\u5EFA\\u8BAE\\u76F4\\u63A5\\u4FEE\\u6539\\uFF09\\n/etc/fail2ban/jail.local - \\u7528\\u6237\\u81EA\\u5B9A\\u4E49\\u914D\\u7F6E\\uFF08\\u63A8\\u8350\\u5728\\u6B64\\u4FEE\\u6539\\uFF09\"), mdx(\"h4\", null, \"fail2ban \\u5E38\\u7528\\u547D\\u4EE4\"), mdx(\"p\", null, \"\\u542F\\u52A8/\\u505C\\u6B62/\\u91CD\\u542F\\u670D\\u52A1\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo systemctl start fail2ban    # \\u542F\\u52A8\\u670D\\u52A1\\nsudo systemctl stop fail2ban     # \\u505C\\u6B62\\u670D\\u52A1\\nsudo systemctl restart fail2ban  # \\u91CD\\u542F\\u670D\\u52A1\\nsudo systemctl enable fail2ban   # \\u8BBE\\u7F6E\\u5F00\\u673A\\u81EA\\u542F\\n\")), mdx(\"h4\", null, \"\\u67E5\\u770B\\u670D\\u52A1\\u72B6\\u6001\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo systemctl status fail2ban\\n\")), mdx(\"h4\", null, \"\\u67E5\\u770B fail2ban-client \\u7684\\u72B6\\u6001\\uFF0C\\u5982\\u542F\\u7528\\u4E86\\u5BF9\\u54EA\\u4E9B\\u670D\\u52A1\\u7684\\u4FDD\\u62A4\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo fail2ban-client status\\n\\n// \\u9ED8\\u8BA4\\u60C5\\u51B5\\u4E0B\\u53EA\\u5F00\\u542F\\u4E86\\u5BF9 ssh \\u7684\\u4FDD\\u62A4\\nStatus\\n|- Number of jail:  1\\n`- Jail list:   sshd\\n\")), mdx(\"h4\", null, \"\\u67E5\\u770B\\u88AB\\u5C01\\u7981\\u7684 IP\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo fail2ban-client status sshd\\n\")), mdx(\"h4\", null, \"\\u89E3\\u5C01\\u7279\\u5B9A IP\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo fail2ban-client set sshd unbanip 192.168.1.100\\n\")), mdx(\"h4\", null, \"\\u624B\\u52A8\\u5C01\\u7981 IP\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo fail2ban-client set sshd banip 192.168.1.100\\n\")), mdx(\"h3\", null, \"\\u5E38\\u89C1filter\\u53CA\\u5176\\u4F4D\\u7F6E\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"ls /etc/fail2ban/filter.d\\n\")), mdx(\"h3\", null, \"\\u67E5\\u770B\\u65E5\\u5FD7\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"tail -f /var/log/fail2ban.log\\n\")), mdx(\"h3\", null, \"\\u6DFB\\u52A0\\u81EA\\u5B9A\\u4E49filter\\uFF0C\\u6CE8\\u610Ffilter \\u7684\\u540D\\u5B57\\u4E0D\\u80FD\\u592A\\u957F\"), mdx(\"p\", null, \"\\u9047\\u5230\\u7684\\u4E00\\u4E2Afilter \\u957F\\u5EA6\\u95EE\\u9898\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"iptables v1.8.7 (nf_tables): chain name `f2b-nginx-botsearch-oneinstack' too long (must be under 29 chars)\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"\\u5982\\u81EA\\u5B9A\\u4E49filter \\u540D\\u79F0\\u4E3A nginx-404\\nvim /etc/fail2ban/filter.d/nginx-404.conf\\n\\n\\u586B\\u5165\\u5982\\u4E0B\\uFF0C\\u8868\\u793A\\u5339\\u914D 404 \\u7684\\u8BBF\\u95EE\\n\\n[Definition]\\nfailregex = ^<HOST> - - \\\\[.*\\\\] \\\"(GET|POST|HEAD) /.* HTTP/\\\\d\\\\.\\\\d\\\" 404\\nignoreregex =\\n\\n\\n\\n\\u7136\\u540E\\u7F16\\u8F91, \\u8868\\u793A 5\\u5206\\u949F\\u5185\\u670910\\u6B21 404 \\u7684\\u8BBF\\u95EE\\u5373\\u7981\\u6B62\\u8BBF\\u95EE \\u4E00\\u4E2A\\u5C0F\\u65F6\\nvim /etc/fail2ban/jail.local\\n\\n\\n[nginx-404]\\nenabled  = true\\nfilter   = nginx-404\\nlogpath  = /data/wwwlogs/*_nginx.log\\nbackend  = polling\\nport     = http,https\\nmaxretry = 10\\nfindtime = 120\\nbantime  = 3600\\n\\n\\n\\u7136\\u540E\\u91CD\\u542F\\nsudo systemctl restart fail2ban\\n\\n\\u67E5\\u770B\\u81EA\\u5B9A\\u4E49filter nginx-404 \\u7684\\u72B6\\u6001\\nsudo fail2ban-client status nginx-404\\n\")), mdx(\"h3\", null, \"\\u9488\\u5BF9wordpress \\u7684filter\"), mdx(\"p\", null, \"Block XML-RPC brute force\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"vim /etc/fail2ban/filter.d/wordpress-xmlrpc.conf\\n\\n[Definition]\\nfailregex = ^<HOST> .*\\\"POST\\\\s+/{1,}xmlrpc\\\\.php\\n\\n\\n\\nvim /etc/fail2ban/jail.local\\n\\n[wordpress-xmlrpc]\\nenabled = true\\nfilter = wordpress-xmlrpc\\nlogpath = /data/wwwlogs/*_nginx.log\\nbackend  = polling\\nmaxretry = 3\\nfindtime = 300\\nbantime = 3600\\naction = iptables[name=wordpress-xmlrpc, port=http, protocol=tcp]\\n\")), mdx(\"p\", null, \"wordpress-login (Protect /wp-login.php)\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"vim /etc/fail2ban/filter.d/wordpress-login.conf\\n\\n[Definition]\\nfailregex = <HOST> -.*\\\"(GET|POST) \\\\/*wp-login\\\\.php\\nignoreregex =\\n\\n\\n\\nvim /etc/fail2ban/jail.local\\n\\n[wordpress-login]\\nenabled = true\\nfilter = wordpress-login\\nlogpath = /data/wwwlogs/*_nginx.log\\nbackend  = polling\\nmaxretry = 5\\nfindtime = 600\\nbantime = 3600\\naction = iptables[name=wordpress-login, port=http, protocol=tcp]\\n\\n\\n\\n\\u5E38\\u89C1\\u95EE\\u9898\\uFF1A\\n\\n\\u5982\\u679C\\u8BBE\\u7F6E\\u4E86\\u5177\\u4F53\\u7684 logpath\\n\\u9700\\u8981\\u8BBE\\u7F6E\\nbackend  = polling\\n\\u4F7F\\u5176\\u751F\\u6548\\nbackend = polling \\u2014 this disables the systemd journal reading and enables direct file reading\\n\")), mdx(\"h3\", null, \"\\u9488\\u5BF9\\u9891\\u7E41\\u8BF7\\u6C42\\u7684filter\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"Create the filter\\n\\nvim /etc/fail2ban/filter.d/nginx-req-limit.conf\\n\\n[Definition]\\n# Match any GET/POST request from an IP\\nfailregex = ^<HOST> -.*\\\"(GET|POST|HEAD) .* HTTP/1\\\\.[01]\\\" \\\\d+ .*$\\n\\nignoreregex =\\n\\n\\n\\n\\n# Add the jail in \\nvim /etc/fail2ban/jail.local\\n\\n\\n[nginx-req-limit]\\nenabled   = true\\nport      = http,https\\nfilter    = nginx-req-limit\\nlogpath   = /data/wwwlogs/*_nginx.log\\nmaxretry  = 100\\nfindtime  = 60\\nbantime   = 3600\\n\\n# Escalation: each repeat offense multiplies ban time\\nbantime.increment  = true\\nbantime.multiplier = 2\\nbantime.maxtime    = 604800\\n\\n\")), mdx(\"h3\", null, \"Apply CPU Quota to PHP-FPM\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Find your PHP-FPM service name\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"systemctl list-units | grep fpm\\n\\n// it will show services like:\\n// php-fpm-83.service\\n\")), mdx(\"ol\", {\n    \"start\": 2\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Create a systemd override file\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo systemctl edit php-fpm-83.service\\n\")), mdx(\"ol\", {\n    \"start\": 3\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"This opens an empty override file in your editor. Add:\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"[Service]\\nCPUAccounting=true\\nCPUQuota=160%\\n\")), mdx(\"p\", null, \"CPUAccounting=true enables CPU tracking.\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"CPUQuota=160% caps PHP-FPM at 1.6 cores worth of CPU.\"), mdx(\"ol\", {\n    \"start\": 4\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Reload systemd and restart PHP-FPM\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo systemctl daemon-reexec\\nsudo systemctl restart php-fpm-83.service\\n\")), mdx(\"ol\", {\n    \"start\": 5\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Verify Quota is Active\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"systemd-cgtop\\n\")), mdx(\"h3\", null, \"restart services if load or memory usage is too high\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"\\n\\nvim /usr/local/bin/server-watchdog.sh\\n\\n#!/bin/bash\\n# Simple watchdog for high load or memory usage\\n# Logs to /var/log/watchdog.log\\n\\nLOG_FILE=\\\"/var/log/watchdog.log\\\"\\nMAX_LOAD=5      # if load avg > 10 , 1 core:2-3, 2 cores: 4-5, 4 cores: 8-10, 8 cores: 15-20\\nMAX_MEM=85       # if memory usage > 85%, 1\\u20132 GB: 80, 4 GB: 85, 8+ GB: 90\\n\\nSERVICES=(\\\"nginx\\\" \\\"mysql\\\" \\\"php-fpm-84\\\" \\\"php-fpm-83\\\" \\\"php-fpm-82\\\")\\n\\n# Ensure log file exists and has correct permissions\\nif [ ! -f \\\"$LOG_FILE\\\" ]; then\\n    touch \\\"$LOG_FILE\\\"\\n    chmod 644 \\\"$LOG_FILE\\\"\\nfi\\n\\nwhile true; do\\n    LOAD=$(awk '{print int($1)}' /proc/loadavg)\\n    MEM=$(free | awk '/Mem:/ {printf(\\\"%.0f\\\", $3/$2 * 100)}')\\n\\n    if [ \\\"$LOAD\\\" -gt \\\"$MAX_LOAD\\\" ] || [ \\\"$MEM\\\" -gt \\\"$MAX_MEM\\\" ]; then\\n        echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - \\u26A0\\uFE0F High load detected (Load=$LOAD, Mem=$MEM%)\\\" >> \\\"$LOG_FILE\\\"\\n\\n        # Restart critical services\\n        for svc in \\\"${SERVICES[@]}\\\"; do\\n            if systemctl is-active --quiet \\\"$svc\\\"; then\\n                systemctl restart \\\"$svc\\\"\\n                echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - Restarted service: $svc\\\" >> \\\"$LOG_FILE\\\"\\n            fi\\n        done\\n\\n        sleep 60\\n\\n        # Recheck load after restart\\n        LOAD_NOW=$(awk '{print int($1)}' /proc/loadavg)\\n        if [ \\\"$LOAD_NOW\\\" -gt \\\"$MAX_LOAD\\\" ]; then\\n            echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - \\u2757 Load still high after restart, rebooting...\\\" >> \\\"$LOG_FILE\\\"\\n            /sbin/reboot\\n        fi\\n    fi\\n\\n    sleep 30\\ndone\\n\\n\\n\\nMake it executable:\\nsudo chmod +x /usr/local/bin/server-watchdog.sh\\n\\n\\n\\nvim /etc/systemd/system/server-watchdog.service\\n\\n[Unit]\\nDescription=Simple watchdog for high load recovery\\nAfter=network.target\\n\\n[Service]\\nType=simple\\nExecStart=/usr/local/bin/server-watchdog.sh\\nRestart=always\\nRestartSec=30\\n\\n[Install]\\nWantedBy=multi-user.target\\n\\n\")), mdx(\"p\", null, \"Then reload and start the service:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo systemctl daemon-reload\\nsudo systemctl enable server-watchdog\\nsudo systemctl start server-watchdog\\n\")), mdx(\"h3\", null, \"\\u67E5\\u770Bpid\\u7A0B\\u5E8F\\u662F\\u7531\\u54EA\\u4E2Aphp\\u6587\\u4EF6\\u5F00\\u59CB\\u6267\\u884C\\u7684\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"sudo lsof -p pid | grep \\\"\\\\.php\\\"\\n\\nsudo lsof -p 340314 | grep \\\"\\\\.php\\\"\\n\")), mdx(\"h3\", null, \"\\u4F7F\\u7528nginx \\u548C GeoIP2 \\u963B\\u6B62\\u67D0\\u5730\\u533Aip\\u8BBF\\u95EE\"), mdx(\"h4\", null, \"Install GeoIP2 for Nginx\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"// \\u4E89\\u5BF9\\u5982\\u4E0B\\u7CFB\\u7EDF\\u7EA7\\u5B89\\u88C5\\u7684nginx\\uFF0C\\u5982\\u679C\\u662F\\u4F7F\\u7528nginx \\u5B89\\u88C5\\u7684\\uFF0C\\u9700\\u8981\\u53E6\\u5916\\u7F16\\u8BD1geoip2\\u6A21\\u5757\\nsudo apt update\\nsudo apt install nginx libnginx-mod-http-geoip2\\n\")), mdx(\"h4\", null, \"Download MaxMind GeoLite2 database\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"\\u5982\\u679C\\u6CA1\\u6709 MaxMind GeoLite2 \\u8D26\\u53F7\\uFF0C\\u521B\\u5EFAlicense-key\\nCreate an account at MaxMind and get a license key.\\nhttps://www.maxmind.com/en/accounts/current/license-key\\n\\n\\n\\nmkdir -p /usr/share/GeoIP\\ncd /usr/share/GeoIP\\n\\n\\nwget -O GeoLite2-Country.tar.gz \\\\\\n\\\"https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_KEY&suffix=tar.gz\\\"\\n\\n\\ntar -xzf GeoLite2-Country.tar.gz\\n\\n\\u4F1A\\u5F97\\u5230\\u6587\\u4EF6\\u5939\\u5982\\uFF1A\\nGeoLite2-Country_20260102\\n\\n\\u91CC\\u9762\\u4F1A\\u6709\\nGeoLite2-Country.mmdb\\n\\n\\u5C06\\u5176\\u79FB\\u5230/usr/share/GeoIP\\u4E0B\\nmv /usr/share/GeoIP/GeoLite2-Country_20260102/GeoLite2-Country.mmdb /usr/share/GeoIP\\n\")), mdx(\"h4\", null, \"Configure GeoIP2 in Nginx\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"\\u7F16\\u8F91\\u603Bnginx \\u914D\\u7F6E\\u6587\\u4EF6,\\u5177\\u4F53\\u4F4D\\u7F6E\\u89C6\\u60C5\\u51B5\\u800C\\u5B9A\\n\\nvim /usr/local/nginx/conf/nginx.conf\\n\\n\\nInside http {} add:\\n\\n\\ngeoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {\\n    $geoip2_country_code country iso_code;\\n}\\n\")), mdx(\"h4\", null, \"Block China only for a.com\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"\\u4F4D\\u7F6E\\u89C6\\u60C5\\u51B5\\u800C\\u5B9A\\nvim /usr/local/nginx/conf/vhost/a.com\\n\\n\\n\\u505A\\u5982\\u4E0B\\u4FEE\\u6539\\nmap $geoip2_country_code $block_china {\\n    default 0;\\n    CN 1;\\n}\\n\\nserver {\\n    server_name a.com www.a.com;\\n\\n    if ($block_china) {\\n        return 403;\\n    }\\n\\n    ...\\n}\\n\")));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#fail2ban-安装与配置","title":"fail2ban 安装与配置","items":[{"url":"#基本配置","title":"基本配置"},{"url":"#fail2ban-常用命令","title":"fail2ban 常用命令"},{"url":"#查看服务状态","title":"查看服务状态"},{"url":"#查看-fail2ban-client-的状态如启用了对哪些服务的保护","title":"查看 fail2ban-client 的状态，如启用了对哪些服务的保护"},{"url":"#查看被封禁的-ip","title":"查看被封禁的 IP"},{"url":"#解封特定-ip","title":"解封特定 IP"},{"url":"#手动封禁-ip","title":"手动封禁 IP"}]},{"url":"#常见filter及其位置","title":"常见filter及其位置"},{"url":"#查看日志","title":"查看日志"},{"url":"#添加自定义filter注意filter-的名字不能太长","title":"添加自定义filter，注意filter 的名字不能太长"},{"url":"#针对wordpress-的filter","title":"针对wordpress 的filter"},{"url":"#针对频繁请求的filter","title":"针对频繁请求的filter"},{"url":"#apply-cpu-quota-to-php-fpm","title":"Apply CPU Quota to PHP-FPM"},{"url":"#restart-services-if-load-or-memory-usage-is-too-high","title":"restart services if load or memory usage is too high"},{"url":"#查看pid程序是由哪个php文件开始执行的","title":"查看pid程序是由哪个php文件开始执行的"},{"url":"#使用nginx-和-geoip2-阻止某地区ip访问","title":"使用nginx 和 GeoIP2 阻止某地区ip访问","items":[{"url":"#install-geoip2-for-nginx","title":"Install GeoIP2 for Nginx"},{"url":"#download-maxmind-geolite2-database","title":"Download MaxMind GeoLite2 database"},{"url":"#configure-geoip2-in-nginx","title":"Configure GeoIP2 in Nginx"},{"url":"#block-china-only-for-acom","title":"Block China only for a.com"}]}]},"parent":{"relativePath":"linux/linux-security.md"},"frontmatter":{"metaTitle":"linux 安全，Linux 常用安全软件","metaDescription":"linux 安全，Linux 常用安全软件"}},"allMdx":{"edges":[{"node":{"fields":{"slug":"/aws-cli","title":"aws cli"}}},{"node":{"fields":{"slug":"/blob","title":"blob"}}},{"node":{"fields":{"slug":"/chatwoot","title":"chatwoot live chat"}}},{"node":{"fields":{"slug":"/codeblock","title":"Syntax Highlighting"}}},{"node":{"fields":{"slug":"/computer-basic","title":"computer basic"}}},{"node":{"fields":{"slug":"/constellation","title":"星座"}}},{"node":{"fields":{"slug":"/css-center","title":"css center"}}},{"node":{"fields":{"slug":"/css-effect","title":"css effect"}}},{"node":{"fields":{"slug":"/css-modules","title":"Css Modules"}}},{"node":{"fields":{"slug":"/cyberpanel","title":"cyberpanel"}}},{"node":{"fields":{"slug":"/douyin","title":"抖音"}}},{"node":{"fields":{"slug":"/elastic-search","title":"Elastic Search"}}},{"node":{"fields":{"slug":"/elementor","title":"elementor"}}},{"node":{"fields":{"slug":"/es6","title":"js es6, es6 spread operator"}}},{"node":{"fields":{"slug":"/es6class","title":"js class"}}},{"node":{"fields":{"slug":"/ffmpeg","title":"ffmpeg"}}},{"node":{"fields":{"slug":"/friendly-link","title":"friendly link"}}},{"node":{"fields":{"slug":"/front-end-interview","title":"frontend interview"}}},{"node":{"fields":{"slug":"/frontend","title":"frontend"}}},{"node":{"fields":{"slug":"/frontendDownload","title":"下载文件"}}},{"node":{"fields":{"slug":"/ftp","title":"ftp"}}},{"node":{"fields":{"slug":"/git","title":"git 常用命令"}}},{"node":{"fields":{"slug":"/graphql","title":"graphql 教程"}}},{"node":{"fields":{"slug":"/http","title":"http"}}},{"node":{"fields":{"slug":"/","title":"Landing Page"}}},{"node":{"fields":{"slug":"/introduction","title":"Introduction"}}},{"node":{"fields":{"slug":"/http_websocket","title":"常见网络协议"}}},{"node":{"fields":{"slug":"/java","title":"java 教程"}}},{"node":{"fields":{"slug":"/javascript","title":"JavaScript"}}},{"node":{"fields":{"slug":"/js-tools","title":"js tools"}}},{"node":{"fields":{"slug":"/js_this_closure","title":"js this"}}},{"node":{"fields":{"slug":"/koajs","title":"Koajs"}}},{"node":{"fields":{"slug":"/lerna","title":"lerna study"}}},{"node":{"fields":{"slug":"/librechat","title":"Libra chat"}}},{"node":{"fields":{"slug":"/markdown_syntax","title":"markdown"}}},{"node":{"fields":{"slug":"/ms-azure-ai-faq","title":"microsoft azure ai FAQ"}}},{"node":{"fields":{"slug":"/ms-azure","title":"MS AZURE"}}},{"node":{"fields":{"slug":"/nodejs","title":"nodejs 的安装和使用"}}},{"node":{"fields":{"slug":"/npm-yarn","title":"Npm Yarn"}}},{"node":{"fields":{"slug":"/openclaw","title":"openclaw 教程"}}},{"node":{"fields":{"slug":"/php","title":"php"}}},{"node":{"fields":{"slug":"/pm2","title":"pm2 常用快捷键"}}},{"node":{"fields":{"slug":"/python","title":"Python 教程"}}},{"node":{"fields":{"slug":"/reactjs","title":"reactjs"}}},{"node":{"fields":{"slug":"/seo","title":"seo"}}},{"node":{"fields":{"slug":"/strapi","title":"strapi"}}},{"node":{"fields":{"slug":"/sublime","title":"sublime 常用快捷键"}}},{"node":{"fields":{"slug":"/tailwindcss","title":"tailwindcss"}}},{"node":{"fields":{"slug":"/vscode","title":"vscode 常用快捷键"}}},{"node":{"fields":{"slug":"/vue3-interview","title":"vuejs3"}}},{"node":{"fields":{"slug":"/vue3","title":"vuejs"}}},{"node":{"fields":{"slug":"/wechat-mini-programs","title":"微信小程序"}}},{"node":{"fields":{"slug":"/wordpress","title":"wordpress study"}}},{"node":{"fields":{"slug":"/codeblock/1-index","title":"Sub Page"}}},{"node":{"fields":{"slug":"/elementor/custom-product-archive","title":"async, await, promise 面试题"}}},{"node":{"fields":{"slug":"/graphql/1-queries","title":"graphql queries"}}},{"node":{"fields":{"slug":"/graphql/2-mutations","title":"graphql Mutations"}}},{"node":{"fields":{"slug":"/graphql/3-apiResponse","title":"graphql queries"}}},{"node":{"fields":{"slug":"/frontend/async-await-promise","title":"async, await, promise 面试题"}}},{"node":{"fields":{"slug":"/frontend/browser-compatibility","title":"Browser Compatibility"}}},{"node":{"fields":{"slug":"/frontend/browser","title":"浏览器渲染"}}},{"node":{"fields":{"slug":"/frontend/css-flex","title":"css flex 布局"}}},{"node":{"fields":{"slug":"/frontend/css-in-js","title":"css in js"}}},{"node":{"fields":{"slug":"/frontend/css","title":"css 常见问题"}}},{"node":{"fields":{"slug":"/frontend/data-fetching","title":"data fetching"}}},{"node":{"fields":{"slug":"/frontend/es6","title":"es6"}}},{"node":{"fields":{"slug":"/frontend/eslint","title":"ESLint"}}},{"node":{"fields":{"slug":"/frontend/frontend-app-cache","title":"前端应用缓存问题"}}},{"node":{"fields":{"slug":"/nodebb-forum","title":"nodebb forum"}}},{"node":{"fields":{"slug":"/nestjs","title":"nestjs study"}}},{"node":{"fields":{"slug":"/multi-language-server-location","title":"多语言营销服务器选择"}}},{"node":{"fields":{"slug":"/frontend/javascript-loop","title":"js loop"}}},{"node":{"fields":{"slug":"/frontend/js-design-patterns","title":"js 设计模式"}}},{"node":{"fields":{"slug":"/frontend/object-oriented-program","title":"js 面向对象"}}},{"node":{"fields":{"slug":"/frontend/package.json-module-version","title":"package.json 版本说明"}}},{"node":{"fields":{"slug":"/frontend/page-event","title":"page event"}}},{"node":{"fields":{"slug":"/frontend/regex","title":"regex, 正则表达式常用方法"}}},{"node":{"fields":{"slug":"/frontend/typescript","title":"typescript 学习"}}},{"node":{"fields":{"slug":"/frontend/unit-test","title":"前端单元测试"}}},{"node":{"fields":{"slug":"/frontend/vue","title":"Vue"}}},{"node":{"fields":{"slug":"/frontend/web-accessibility","title":"web accessibility"}}},{"node":{"fields":{"slug":"/frontend/web-vitals","title":"网络性能重要指标"}}},{"node":{"fields":{"slug":"/frontend/webpack-babel","title":"Webpack Babel"}}},{"node":{"fields":{"slug":"/frontend/window-object","title":"Window Object"}}},{"node":{"fields":{"slug":"/java/1-get-started","title":"Java 入门"}}},{"node":{"fields":{"slug":"/java/2-syntax","title":"Java 语法"}}},{"node":{"fields":{"slug":"/java/3-comments","title":"Java 注释"}}},{"node":{"fields":{"slug":"/java/4-variables","title":"Java 变量"}}},{"node":{"fields":{"slug":"/java/5-spring-boot","title":"什么是 spring boot, Spring 框架"}}},{"node":{"fields":{"slug":"/java/java-inteview","title":"java 面试题"}}},{"node":{"fields":{"slug":"/koajs/koa_response","title":"koa response"}}},{"node":{"fields":{"slug":"/koajs/koa常见问题","title":"KOA 常见问题"}}},{"node":{"fields":{"slug":"/linux/aws","title":"aws 相关"}}},{"node":{"fields":{"slug":"/linux/bt","title":"bt panel"}}},{"node":{"fields":{"slug":"/linux/ci-jenkins","title":"CI Jenkins"}}},{"node":{"fields":{"slug":"/linux/crontab","title":"crontab 常用快捷键"}}},{"node":{"fields":{"slug":"/linux/curl","title":"curl 命令"}}},{"node":{"fields":{"slug":"/linux/docker","title":"docker 常用快捷键"}}},{"node":{"fields":{"slug":"/linux/interview-question","title":"常见面试题"}}},{"node":{"fields":{"slug":"/linux/linux-security","title":"linux 安全"}}},{"node":{"fields":{"slug":"/linux/linux","title":"linux 常用快捷键"}}},{"node":{"fields":{"slug":"/linux/shell","title":"shell 命令"}}},{"node":{"fields":{"slug":"/linux/ssh","title":"ssh"}}},{"node":{"fields":{"slug":"/linux/oss","title":"阿里云oss"}}},{"node":{"fields":{"slug":"/linux/vi-vim","title":"Linux vi vim"}}},{"node":{"fields":{"slug":"/noSql/redis","title":"redis 常用命令"}}},{"node":{"fields":{"slug":"/reactjs/dva_umi","title":"umi js, dva 教程"}}},{"node":{"fields":{"slug":"/reactjs/fastRefresh","title":"Fast Refresh"}}},{"node":{"fields":{"slug":"/reactjs/gatsbyjs","title":"gatsby js, dva 教程"}}},{"node":{"fields":{"slug":"/reactjs/nextjs","title":"nextjs 笔记"}}},{"node":{"fields":{"slug":"/reactjs/react-hooks","title":"react hooks"}}},{"node":{"fields":{"slug":"/reactjs/react-usestate-from-sessionstorage","title":"react useState from sessionStorage"}}},{"node":{"fields":{"slug":"/reactjs/reactBasic","title":"react basic"}}},{"node":{"fields":{"slug":"/reactjs/reactComponent","title":"react component"}}},{"node":{"fields":{"slug":"/reactjs/reactContext","title":"react context"}}},{"node":{"fields":{"slug":"/reactjs/reactFiber","title":"react fiber"}}},{"node":{"fields":{"slug":"/reactjs/reactHOC","title":"react HOC"}}},{"node":{"fields":{"slug":"/reactjs/reactInterview","title":"React Interview"}}},{"node":{"fields":{"slug":"/reactjs/reactPerformance","title":"react performance"}}},{"node":{"fields":{"slug":"/reactjs/reactPropTypes","title":"react propTypes"}}},{"node":{"fields":{"slug":"/reactjs/reactRef","title":"react Ref"}}},{"node":{"fields":{"slug":"/reactjs/redux-mobx","title":"react mobx"}}},{"node":{"fields":{"slug":"/reactjs/ssr-ssg-csr","title":"react mobx"}}},{"node":{"fields":{"slug":"/sql/basic","title":"sql"}}},{"node":{"fields":{"slug":"/sql/mysql","title":"mysql"}}},{"node":{"fields":{"slug":"/sql/postgresql","title":"postgresql"}}},{"node":{"fields":{"slug":"/sql/sequelize","title":"Sequelize"}}},{"node":{"fields":{"slug":"/linux/oneinstack","title":"oneinstack 命令, 笔记"}}},{"node":{"fields":{"slug":"/linux/oauth","title":"oauth"}}},{"node":{"fields":{"slug":"/linux/nginx","title":"nginx 教程"}}}]}},"pageContext":{"id":"4e7c4a6d-303e-54b8-bf6c-b349faf697a8"}},"staticQueryHashes":["2619113677","3706406642","417421954"]}