{"id":378,"date":"2026-01-02T19:16:10","date_gmt":"2026-01-02T11:16:10","guid":{"rendered":"https:\/\/tys.fun\/?p=378"},"modified":"2026-01-15T16:05:20","modified_gmt":"2026-01-15T08:05:20","slug":"safety-on-a-new-vps","status":"publish","type":"post","link":"https:\/\/www.tys.fun\/?p=378","title":{"rendered":"Safety on a New VPS"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><h1>Safety on a New VPS<\/h1>\n<p>We often need to buy servers for service scalability, bypassing <em>The Firewall<\/em>, or for various other reasons. However, I\u2019ve noticed that many people are deploying services in an unsafe way, and some of their practices are actually exposing vulnerabilities to attackers. So here are some security tips you should keep in mind after booting up a new VPS.<\/p>\n<h2>SSH Login<\/h2>\n<p>We\u2019re going to change the configuration of <code>sshd<\/code>, but there are a few things you should be aware of. If your VPS provider uses <code>cloud-init<\/code> (which is quite common), there will be a <code>50-cloud-init.conf<\/code> file in the <code>\/etc\/ssh\/sshd_config.d<\/code> directory. Files in this directory override the same options in <code>\/etc\/ssh\/sshd_config<\/code>, so a better (and recommended) way to change the configuration is to create a <code>00-custom.conf<\/code> file in <code>\/etc\/ssh\/sshd_config.d<\/code>. The \u201c00\u201d prefix means this file will be loaded with the highest priority and will override the same settings in any other files.<\/p>\n<h3>Login Port<\/h3>\n<p>By default, port 22 is used for SSH connections, but keeping this port open attracts a lot of brute\u2011force attacks. Changing it to another port is a common practice to harden your server.<\/p>\n<p>Adding the following line to the <code>00-custom.conf<\/code> file will change the port to 2025. Of course, you can use any port that isn\u2019t already in use by other software.<\/p>\n<pre><code class=\"language-sshd\">Port 2025\n<\/code><\/pre>\n<p>Keep in mind that this is not a real security measure; it only reduces noise from automated scans and brute\u2011force attempts.<\/p>\n<h3>Authentication<\/h3>\n<p>This is the most important part of SSH security. First of all, I strongly recommend not using password authentication for any server exposed to the Internet. Instead, you should use key pairs to log in to the server. For instructions on how to generate key pairs, you can refer to <a href=\"https:\/\/www.ssh.com\/academy\/ssh\/keygen\">SSH Academy<\/a>. To disable password logins, add the following line:<\/p>\n<pre><code class=\"language-sshd\">PasswordAuthentication no\n<\/code><\/pre>\n<p>Logging in directly as <code>root<\/code> is also not very safe \u2014 a single mistaken command like <code>rm -rf \/<\/code> can be disastrous \u2014 but <code>root<\/code> privileges are often needed for maintenance. Whether you allow direct <code>root<\/code> login is up to you. You can choose to disable it:<\/p>\n<pre><code class=\"language-sshd\">PermitRootLogin no\n<\/code><\/pre>\n<p>or just disable password logins for <code>root<\/code>:<\/p>\n<pre><code class=\"language-sshd\">PermitRootLogin prohibit-password\n<\/code><\/pre>\n<p>However, this is actually not necessary, because we have already disabled password logins earlier.<\/p>\n<p>You can always add more features to harden the server, such as <code>fail2ban<\/code> or two\u2011factor authentication (2FA).<\/p>\n<p>The configuration I recommend is:<\/p>\n<pre><code class=\"language-sshd\"># \/etc\/ssh\/sshd_config.d\/00-custom.conf\nPort 2025\nPasswordAuthentication no\n# Optional\n# PermitRootLogin no\n<\/code><\/pre>\n<p>The whole options available could be found at <a href=\"https:\/\/www.man7.org\/linux\/man-pages\/man5\/sshd_config.5.html\">man page<\/a>.<\/p>\n<p>After changing the configuration, restart the SSH service:<\/p>\n<pre><code class=\"language-bash\"># If you are using Ubuntu\/Debian\nsudo systemctl restart ssh\n<\/code><\/pre>\n<p><strong>Make sure you can connect to your server in a new session before closing the existing connection!<\/strong><\/p>\n<h2>Firewall<\/h2>\n<p>For people who just want to drop unwanted packets and don\u2019t need to manipulate traffic, you can simply use <code>ufw<\/code> instead of <code>iptables<\/code> or <code>nftables<\/code>. It\u2019s quite simple.<\/p>\n<h3>Use <code>ufw<\/code><\/h3>\n<p>Make sure you have it installed. If not, install it with:<\/p>\n<pre><code class=\"language-bash\"># Ubuntu\/Debian\nsudo apt update &amp;&amp; sudo apt install -y ufw\n<\/code><\/pre>\n<p>By default, <code>ufw<\/code> denies incoming packets, allows outgoing packets, and denies routed packets. Normally we need to connect to the server over SSH, so allow it by running:<\/p>\n<pre><code class=\"language-bash\"># Note: If you changed the SSH port in the previous section,\n# update the port number here, otherwise you will not be able to\n# connect to the server.\nsudo ufw allow 2015\/tcp\n<\/code><\/pre>\n<p>If you use a static IP address to access your server, it\u2019s safer to allow only whitelisted IPs to access the SSH port. In that case, the rule should look like this:<\/p>\n<pre><code class=\"language-bash\">sudo ufw allow from 12.34.56.78 proto tcp to any port 2015\n<\/code><\/pre>\n<p>If your server is going to provide HTTP\/HTTPS or any other services, add the corresponding rules:<\/p>\n<pre><code class=\"language-bash\">sudo ufw allow 443\nsudo ufw allow 80\n<\/code><\/pre>\n<p>After adding all the firewall rules, you can check them at any time with:<\/p>\n<pre><code class=\"language-bash\">sudo ufw status\n<\/code><\/pre>\n<p>If everything looks good, you can enable it now:<\/p>\n<pre><code class=\"language-bash\">sudo ufw enable\n<\/code><\/pre>\n<h3>Use <code>nftables<\/code><\/h3>\n<p>On recent versions of Ubuntu and Debian, <code>nftables<\/code> is installed but not enabled by default, and you can edit the rules before enabling it. <code>nftables<\/code> uses <code>\/etc\/nftables.conf<\/code> by default. Remember to back it up before editing, just in case.<\/p>\n<p>The file should look like this:<\/p>\n<pre><code class=\"language-nftables\">#!\/usr\/sbin\/nft -f\n\nflush ruleset\n\ntable inet filter {\n    chain input {\n        type filter hook input priority filter;\n    }\n    chain forward {\n        type filter hook forward priority filter;\n    }\n    chain output {\n        type filter hook output priority filter;\n    }\n}\n<\/code><\/pre>\n<p>Now we want to allow SSH connections and some other services while denying all unexpected packets, so add the rules in the <code>input<\/code> chain:<\/p>\n<pre><code class=\"language-nftables\">chain input {\n    type filter hook input priority filter; policy drop;\n\n    # allow local loop\n    iif &quot;lo&quot; accept\n\n    # allow established connections\n    ct state established,related accept\n\n    # drop all invalid packages\n    ct state invalid drop\n    \n    # Allow ipv6 router discovery, neighbor-solicitation, etc\n    ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, packet-too-big } accept\n    \n    # Allow ping(Optional)\n    # ip protocol icmp accept\n    # ip6 nexthdr icmpv6 accept\n\n    # Allow SSH\n    tcp dport 2015 accept\n    \n    # Allow HTTP\/HTTPS traffic\n    tcp dport 80 accept\n    tcp dport 443 accept\n    # If your site supports QUIC\n    udp dport 443 accpept\n\n}\n<\/code><\/pre>\n<p>If you only want a specific IP to access SSH, change the rule to:<\/p>\n<pre><code class=\"language-nftables\">tcp dport 2015 ip saddr { 12.34.56.78 } accept\n<\/code><\/pre>\n<p>Then the whole configuration file should look like this:<\/p>\n<pre><code class=\"language-nftables\">#!\/usr\/sbin\/nft -f\n\nflush ruleset\n\ntable inet filter {\n    chain input {\n        type filter hook input priority filter; policy drop;\n\n        # Allow local loop\n        iif &quot;lo&quot; accept\n\n        # Allow established connections\n        ct state established,related accept\n\n        # Drop all invalid packages\n        ct state invalid drop\n\n        # Allow ipv6 router discovery, neighbor-solicitation, etc\n        ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, packet-too-big } accept\n\t\t\t\t\n        # Allow ping(Optional)\n        # ip protocol icmp accept\n        # ip6 nexthdr icmpv6 accept\n\n        # Allow SSH\n        tcp dport 2015 accept\n        \n        # Allow HTTP\/HTTPS traffic\n        tcp dport 80 accept\n        tcp dport 443 accept\n        # If your site supports QUIC\n        udp dport 443 accpept\n\n    }\n    chain forward {\n        type filter hook forward priority filter;\n    }\n    chain output {\n        type filter hook output priority filter;\n    }\n}\n<\/code><\/pre>\n<p>After editing the configuration, check it with:<\/p>\n<pre><code class=\"language-bash\">sudo nft --check -f \/etc\/nftables.conf\n<\/code><\/pre>\n<p>If there\u2019s no output, it means there are no errors, and you can enable it by running:<\/p>\n<pre><code class=\"language-bash\"># On Ubuntu\/Debian\nsudo systemctl enable --now nftables\n<\/code><\/pre>\n<p><strong>Again, you should always check that you can still connect to the server before closing existing connections.<\/strong><\/p>\n<h2>Service Permissions<\/h2>\n<p>Even if you keep using the <code>root<\/code> account for more convenient maintenance, it\u2019s not wise to run all services with <code>root<\/code> privileges, because if a single service is compromised, the entire VPS will be at risk. A simple approach is to create separate accounts with <code>nologin<\/code> shells to run different applications. When running web servers like <code>nginx<\/code>, <code>Apache<\/code>, or <code>Caddy<\/code>, you\u2019ll notice that they only launch the parent process with elevated privileges and use child processes running under accounts like <code>www-data<\/code> to handle requests.<\/p>\n<p>Also, running a script as <code>root<\/code> means you are effectively giving the author <code>root<\/code> privileges for that period of time. Make sure you know what it does before executing any command or script, especially when using the <code>root<\/code> account.<\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;-\u6211\u662f\u5206\u5272\u7ebf&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/p>\n<p>\u8003\u8651\u5230\u672c\u535a\u5ba2\u7684\u53d7\u4f17\u66f4\u591a\u4f7f\u7528\u4e2d\u6587\uff0c\u6240\u4ee5\u8fd8\u662f\u518d\u5199\u4e00\u4efd\u4e2d\u6587\u7248\u672c\u3002<\/p>\n<h1>\u65b0 VPS \u7684\u5b89\u5168\u7ba1\u7406<\/h1>\n<p>\u4e0d\u7ba1\u662f\u4e3a\u4e86\u6269\u5bb9\u670d\u52a1\u3001\u79d1\u5b66\u4e0a\u7f51\u8fd8\u662f\u5c31\u662f\u60f3\u5c6f\uff0c\u5927\u5bb6\u603b\u4f1a\u4e70\u65b0\u670d\u52a1\u5668~~\uff08\u5373\u4f7f\u662f\u5b8c\u5168\u4e0d\u7f3a\uff09~~\u3002\u4f46\u662f\u6700\u8fd1\u53d1\u73b0\u5f88\u591a\u4eba\u90e8\u7f72\u670d\u52a1\u7684\u65b9\u5f0f\u5e76\u4e0d\u5b89\u5168\uff0c\u6709\u4e9b\u751a\u81f3\u662f\u5728\u66b4\u9732\u66f4\u591a\u7684\u653b\u51fb\u9762\u3002\u6240\u4ee5\u5c31\u6709\u4e86\u8fd9\u7bc7\u6587\u7ae0\uff0c\u5199\u4e00\u4e0b\u62ff\u5230 VPS \u4e4b\u540e\u7684\u7b80\u5355\u52a0\u56fa\u3002<\/p>\n<h2>SSH \u767b\u5f55<\/h2>\n<p>\u8fd9\u90e8\u5206\u7684\u8c03\u6574\u9700\u8981\u66f4\u6539 <code>sshd<\/code> \u7684\u914d\u7f6e\uff0c\u6709\u4e00\u4e9b\u70b9\u9700\u8981\u6ce8\u610f\u3002\u5982\u679c\u4f60\u7684 VPS \u5546\u5bb6\u4f7f\u7528\u4e86 <code>cloud-init<\/code> \u8fdb\u884c\u521d\u59cb\u5316\uff08\u975e\u5e38\u5e38\u89c1\uff09\uff0c\u5c31\u4f1a\u6709\u4e00\u4e2a <code>50-cloud-init.conf<\/code> \u6587\u4ef6\u5728 <code>\/etc\/ssh\/sshd_config.d<\/code> \u7684\u8def\u5f84\u4e0b\u3002\u5982\u679c\u8fd9\u4e2a\u6587\u4ef6\u5305\u542b\u4e86\u548c <code>\/etc\/ssh\/sshd_config<\/code> \u4e2d\u76f8\u540c\u7684\u9009\u9879\uff0c\u5219\u4f1a\u8986\u76d6\u8fd9\u4e2a\u9009\u9879\uff0c\u6240\u4ee5\u66f4\u597d\u7684\uff08\u4e5f\u662f\u63a8\u8350\u7684\uff09\u65b9\u5f0f\u662f\u65b0\u5efa\u4e00\u4e2a <code>00-custom.conf<\/code> \u6587\u4ef6\u5728 <code>\/etc\/ssh\/sshd_config.d<\/code> \u8def\u5f84\u4e0b\u3002\u524d\u7f00 \u201c00\u201d \u8868\u793a\u4ed6\u4f1a\u4ee5\u6700\u9ad8\u4f18\u5148\u7ea7\u52a0\u8f7d\u5e76\u8986\u76d6\u5176\u4ed6\u6587\u4ef6\u7684\u6240\u6709\u76f8\u540c\u5173\u952e\u5b57\uff0c\u5373\u4fdd\u8bc1\u8be5\u6587\u4ef6\u7684\u8bbe\u7f6e\u751f\u6548\u3002<\/p>\n<h3>\u767b\u5f55\u7aef\u53e3<\/h3>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cSSH \u8fde\u63a5\u4f7f\u7528 22 \u7aef\u53e3\uff0c\u4f46\u662f\u4f7f\u7528\u8fd9\u4e2a\u7aef\u53e3\u5bb9\u6613\u5438\u5f15\u7206\u7834\u653b\u51fb\u3002\u628a\u5b83\u6539\u4e86\u662f\u4e00\u4e2a\u5f88\u5e38\u89c1\u7684\u89c4\u907f\u66b4\u529b\u653b\u51fb\u7684\u65b9\u5f0f\u3002<\/p>\n<p>\u5728 <code>00-custom.conf<\/code> \u6587\u4ef6\u4e2d\u6dfb\u52a0\u8fd9\u6837\u4e00\u884c\u53ef\u4ee5\u628a\u7aef\u53e3\u6539\u5230 2025\uff0c\u5f53\u7136\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528\u4efb\u4f55\u6ca1\u6709\u88ab\u5176\u4ed6\u8f6f\u4ef6\u5360\u7528\u7684\u7aef\u53e3\u3002<\/p>\n<pre><code class=\"language-sshd\">Port 2025\n<\/code><\/pre>\n<p>\u4e0d\u8fc7\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u8fd9\u53ea\u80fd\u51cf\u5c11\u4e00\u5b9a\u81ea\u52a8\u5316\u626b\u63cf\u548c\u66b4\u529b\u7834\u89e3\u7684\u6570\u91cf\uff0c\u5e76\u4e0d\u80fd\u5e26\u6765\u672c\u8d28\u4e0a\u7684\u5b89\u5168\u6027\u63d0\u5347\u3002<\/p>\n<h3>\u8eab\u4efd\u9a8c\u8bc1<\/h3>\n<p>\u8fd9\u662f SSH \u5b89\u5168\u6700\u5173\u952e\u7684\u90e8\u5206\u3002\u9996\u5148\uff0c\u6211\u6781\u5176\u4e0d\u63a8\u8350\u5728\u4efb\u4f55\u66b4\u9732 SSH \u7aef\u53e3\u5728\u516c\u7f51\u4e0a\u7684\u670d\u52a1\u5668\u53ea\u4f7f\u7528\u5bc6\u7801\u9a8c\u8bc1\uff0c\u800c\u662f\u4f7f\u7528\u5bc6\u94a5\u5bf9\u8fdb\u884c\u767b\u5f55\u3002\u5bf9\u4e8e\u5982\u4f55\u751f\u6210\u5bc6\u94a5\u5bf9\uff0c\u53ef\u4ee5\u53c2\u8003 <a href=\"https:\/\/www.ssh.com\/academy\/ssh\/keygen\">SSH Academy<\/a>\uff0c\u4e2d\u6587\u6559\u7a0b\u53ef\u4ee5\u53c2\u8003 <a href=\"https:\/\/101.lug.ustc.edu.cn\/Ch01\/supplement\/#ssh\">USTC LUG 101\u624b\u518c<\/a>\u3002\u8981\u7981\u7528\u5bc6\u7801\u767b\u5f55\uff0c\u6dfb\u52a0\u8fd9\u6837\u4e00\u884c\uff1a<\/p>\n<pre><code class=\"language-sshd\">PasswordAuthentication no\n<\/code><\/pre>\n<p>\u5176\u6b21\uff0c\u76f4\u63a5\u4f7f\u7528 <code>root<\/code> \u8d26\u53f7\u767b\u5f55\u4e5f\u662f\u4e0d\u592a\u5b89\u5168\u7684\uff0c<s>\u4e07\u4e00\u54ea\u5929\u6572\u51fa\u6765\u4e86 <code>rm -rf \/<\/code> \u5c31\u70b8\u4e86\uff0c<\/s> \u4f46\u662f\u7ef4\u62a4\u670d\u52a1\u5668\u7ecf\u5e38\u9700\u8981 <code>root<\/code> \u6743\u9650\uff0c\u6240\u4ee5\u8981\u4e0d\u8981\u7528 <code>root<\/code> \u767b\u5f55\u81ea\u884c\u51b3\u5b9a\u5427\u3002\u5982\u679c\u9009\u62e9\u5173\u6389 <code>root<\/code> \u767b\u5f55\uff1a<\/p>\n<pre><code class=\"language-sshd\">PermitRootLogin no\n<\/code><\/pre>\n<p>\u6216\u8005\u53ea\u7981\u7528 <code>root<\/code> \u7684\u5bc6\u7801\u767b\u5f55\uff1a<\/p>\n<pre><code class=\"language-sshd\">PermitRootLogin prohibit-password\n<\/code><\/pre>\n<p>\u4f46\u5176\u5b9e\u8fd9\u4e0d\u662f\u5fc5\u8981\u7684\uff0c\u5982\u679c\u4f60\u5df2\u7ecf\u8ddf\u968f\u7b2c\u4e00\u6b65\u7981\u7528\u4e86\u5bc6\u7801\u767b\u5f55\u3002<\/p>\n<p>\u5f53\u7136\u4f60\u4e5f\u53ef\u4ee5\u6dfb\u52a0\u5176\u4ed6\u7684\u7ec4\u4ef6\u6765\u52a0\u56fa SSH\uff0c\u6bd4\u5982\u4f7f\u7528 <code>fail2ban<\/code> \u4ee5\u53ca\u5f15\u5165\u591a\u56e0\u7d20\u8ba4\u8bc1\uff082FA\uff09\u3002<\/p>\n<p>\u6211\u6bd4\u8f83\u63a8\u8350\u7684\u914d\u7f6e\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-sshd\"># \/etc\/ssh\/sshd_config.d\/00-custom.conf\nPort 2025\nPasswordAuthentication no\n# \u53ef\u9009\n# PermitRootLogin no\n<\/code><\/pre>\n<p><code>sshd_config<\/code> \u5176\u5b9e\u6709\u5f88\u591a\u9009\u9879\uff0c\u611f\u5174\u8da3\u53ef\u4ee5\u79fb\u6b65 <a href=\"https:\/\/www.man7.org\/linux\/man-pages\/man5\/sshd_config.5.html\">man page<\/a>\u3002<\/p>\n<p>\u66f4\u6539\u5b8c\u914d\u7f6e\u4e4b\u540e\uff0c\u91cd\u542f <code>ssh<\/code> \u670d\u52a1\uff1a<\/p>\n<pre><code class=\"language-bash\"># \u7528\u7684\u662f Ubuntu\/Debian \u7684\u8bdd\nsudo systemctl restart ssh\n<\/code><\/pre>\n<p><strong>\u6ce8\u610f\uff0c\u4e00\u5b9a\u8981\u786e\u8ba4\u4f60\u80fd\u7528\u65b0\u7684 session \u8fde\u4e0a\u670d\u52a1\u5668\u4e4b\u540e\u518d\u5173\u95ed\u73b0\u6709\u8fde\u63a5\uff01\uff01<\/strong><\/p>\n<h2>\u9632\u706b\u5899<\/h2>\n<p>\u5982\u679c\u4f60\u53ea\u662f\u60f3\u8fc7\u6ee4\u975e\u6cd5\u8bf7\u6c42\u5305\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 <code>ufw<\/code> \u6765\u914d\u7f6e\u800c\u4e0d\u662f\u4f7f\u7528 <code>iptables<\/code> \u6216\u8005 <code>nftales<\/code> \u8fd9\u79cd\u8def\u7531\u8868\uff0c<code>ufw<\/code> \u4f1a\u7b80\u5355\u5f88\u591a\u3002<\/p>\n<h3>\u4f7f\u7528 <code>ufw<\/code><\/h3>\n<p>\u786e\u4fdd\u4f60\u5df2\u7ecf\u5b89\u88c5\u4e86\u5b83\uff0c\u5982\u679c\u6ca1\u6709\u7684\u8bdd\u5c31\u88c5\u4e00\u4e0b\uff1a<\/p>\n<pre><code class=\"language-bash\"># Ubuntu\/Debian\nsudo apt update &amp;&amp; sudo apt install -y ufw\n<\/code><\/pre>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c<code>ufw <\/code>\u4f1a\u62d2\u7edd\u6240\u6709\u5165\u7ad9\u8bf7\u6c42\uff0c\u5141\u8bb8\u6240\u6709\u51fa\u7ad9\u8bf7\u6c42\uff0c\u5e76\u62d2\u7edd\u6240\u6709\u8def\u7531\u8bf7\u6c42\uff08\u5176\u5b9e\u662f forwarding\uff09\u3002\u4e00\u822c\u6765\u8bf4\u6211\u4eec\u9700\u8981\u7528 SSH \u8fde\u63a5\u670d\u52a1\u5668\uff0c\u6240\u4ee5\u8981\u6dfb\u52a0\u76f8\u5173\u89c4\u5219\uff1a<\/p>\n<pre><code class=\"language-bash\"># \u6ce8\u610f\uff01\u5982\u679c\u4f60\u8ddf\u968f\u4e0a\u4e2a\u7ae0\u8282\u66f4\u6539\u4e86 SSH \u7684\u7aef\u53e3\u53f7\uff0c\u8fd9\u91cc\u4e5f\u8981\u6539\uff0c\n# \u4e0d\u7136\u7684\u8bdd\u542f\u52a8\u9632\u706b\u5899\u4f60\u5c31\u8fde\u4e0d\u4e0a\u670d\u52a1\u5668\u4e86\nsudo ufw allow 2015\/tcp\n<\/code><\/pre>\n<p>\u5982\u679c\u4f60\u6709\u9759\u6001 IP \u5730\u5740\u6765\u8bbf\u95ee\u8fd9\u53f0\u670d\u52a1\u5668\uff0c\u4f60\u53ef\u4ee5\u53ea\u5141\u8bb8\u767d\u540d\u5355\u5730\u5740\u8bbf\u95ee SSH \u7aef\u53e3\u3002\u8fd9\u6837\u7684\u8bdd\u89c4\u5219\u5e94\u8be5\u8fd9\u6837\u5199\uff1a<\/p>\n<pre><code class=\"language-bash\">sudo ufw allow from 12.34.56.78 proto tcp to any port 2015\n<\/code><\/pre>\n<p>\u5982\u679c\u4f60\u8981\u63d0\u4f9b\u7f51\u9875\u670d\u52a1\uff08HTTP\/HTTPS\uff09\u6216\u8005\u5176\u4ed6\u4ec0\u4e48\u670d\u52a1\uff0c\u6dfb\u52a0\u5bf9\u5e94\u7684\u89c4\u5219\uff1a<\/p>\n<pre><code class=\"language-bash\">sudo ufw allow 443\nsudo ufw allow 80\n<\/code><\/pre>\n<p>\u6dfb\u52a0\u5b8c\u89c4\u5219\u4e4b\u540e\uff0c\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e0b\uff1a<\/p>\n<pre><code class=\"language-bash\">sudo ufw status\n<\/code><\/pre>\n<p>\u5982\u679c\u770b\u8d77\u6765OK\uff0c\u90a3\u5c31\u53ef\u4ee5\u542f\u52a8\u4e86\uff1a<\/p>\n<pre><code class=\"language-bash\">sudo ufw enable\n<\/code><\/pre>\n<h3>\u4f7f\u7528 <code>nftables<\/code><\/h3>\n<p>\u5728\u65b0\u7248\u672c\u7684 Ubuntu \u548c Debian \u4e2d\uff0c<code>nftables<\/code> \u662f\u9ed8\u8ba4\u5b89\u88c5\u4f46\u4e0d\u542f\u7528\u7684\uff0c\u53ef\u4ee5\u5148\u4fee\u6539\u89c4\u5219\u518d\u542f\u52a8\u670d\u52a1\u3002<code>nftables<\/code> \u9ed8\u8ba4\u4f7f\u7528 <code>\/etc\/nftables.conf<\/code> \u4e2d\u7684\u914d\u7f6e\uff0c\u5efa\u8bae\u5728\u4fee\u6539\u524d\u5907\u4efd\u539f\u59cb\u6587\u4ef6\u3002<\/p>\n<p>\u8fd9\u4e2a\u6587\u4ef6\u5e94\u8be5\u957f\u8fd9\u6837\uff1a<\/p>\n<pre><code class=\"language-nftables\">#!\/usr\/sbin\/nft -f\n\nflush ruleset\n\ntable inet filter {\n    chain input {\n        type filter hook input priority filter;\n    }\n    chain forward {\n        type filter hook forward priority filter;\n    }\n    chain output {\n        type filter hook output priority filter;\n    }\n}\n<\/code><\/pre>\n<p>\u6211\u4eec\u8981\u5141\u8bb8 SSH \u8fde\u63a5\u8fd8\u6709\u4ec0\u4e48\u5176\u4ed6\u670d\u52a1\uff0c\u5e76\u4e14\u4e22\u5f03\u6240\u6709\u4e71\u4e03\u516b\u7cdf\u7684\u5305\uff0c\u5c31\u53ef\u4ee5\u5728 <code>input<\/code> \u94fe\u52a0\u4e0a\u8fd9\u4e9b\u89c4\u5219\uff1a<\/p>\n<pre><code class=\"language-nftables\">chain input {\n    type filter hook input priority filter; policy drop;\n\n    # \u672c\u5730\u73af\u8def\u5f97\u901a\n    iif &quot;lo&quot; accept\n\n    # \u5141\u8bb8\u5df2\u7ecf\u5efa\u7acb\u7684\u8fde\u63a5\n    ct state established,related accept\n\n    # \u4e22\u5f03\u6240\u6709\u72b6\u6001\u65e0\u6548\u7684\u5305\n    ct state invalid drop\n\n    # \u5141\u8bb8 ipv6 \u8def\u7531\u53d1\u73b0\u3001\u90bb\u5c45\u53d1\u73b0\u7b49\u534f\u8bae\n    ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, packet-too-big } accept\n\t\t\n    # \u5141\u8bb8 ping \uff08\u53ef\u9009\uff09\n    # ip protocol icmp accept\n    # ip6 nexthdr icmpv6 accept\n\n    # \u5141\u8bb8 SSH\n    tcp dport 2015 accept\n    \n    # \u5141\u8bb8 HTTP\/HTTPS\n    tcp dport 80 accept\n    tcp dport 443 accept\n    # \u5982\u679c\u4f60\u8981\u652f\u6301 QUIC \u7684\u8bdd\n    udp dport 443 accept\n\n}\n<\/code><\/pre>\n<p>\u5982\u679c\u4f60\u53ea\u60f3\u8ba9\u7279\u5b9a IP \u8bbf\u95ee SSH\uff0c\u628a\u89c4\u5219\u6539\u6210\uff1a<\/p>\n<pre><code class=\"language-nftables\">tcp dport 2015 ip saddr { 12.34.56.78 } accept\n<\/code><\/pre>\n<p>\u8fd9\u6837\u7684\u8bdd\uff0c\u6574\u4e2a\u914d\u7f6e\u6587\u4ef6\u5c31\u6210\u4e86\uff1a<\/p>\n<pre><code class=\"language-nftables\">#!\/usr\/sbin\/nft -f\n\nflush ruleset\n\ntable inet filter {\n    chain input {\n        type filter hook input priority filter; policy drop;\n\n        # \u672c\u5730\u73af\u8def\u5f97\u901a\n        iif &quot;lo&quot; accept\n\n        # \u5141\u8bb8\u5df2\u7ecf\u5efa\u7acb\u7684\u8fde\u63a5\n        ct state established,related accept\n\n        # \u4e22\u5f03\u6240\u6709\u72b6\u6001\u65e0\u6548\u7684\u5305\n        ct state invalid drop\n\n        # \u5141\u8bb8 ipv6 \u8def\u7531\u53d1\u73b0\u3001\u90bb\u5c45\u53d1\u73b0\u7b49\u534f\u8bae\n        ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert, packet-too-big } accept\n        \n        # \u5141\u8bb8 ping \uff08\u53ef\u9009\uff09\n        # ip protocol icmp accept\n        # ip6 nexthdr icmpv6 accept\n\n        # \u5141\u8bb8 SSH\n        tcp dport 2015 accept\n\n        # \u5141\u8bb8 HTTP\/HTTPS\n        tcp dport 80 accept\n        tcp dport 443 accept\n        # \u5982\u679c\u4f60\u8981\u652f\u6301 QUIC \u7684\u8bdd\n        udp dport 443 accept\n        \n    }\n    chain forward {\n        type filter hook forward priority filter;\n    }\n    chain output {\n        type filter hook output priority filter;\n    }\n}\n<\/code><\/pre>\n<p>\u7f16\u8f91\u5b8c\u6587\u4ef6\u4e4b\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fd9\u6761\u547d\u4ee4\u6765\u68c0\u67e5\u662f\u5426\u5b58\u5728\u8bed\u6cd5\u9519\u8bef\uff1a<\/p>\n<pre><code class=\"language-bash\">sudo nft --check -f \/etc\/nftables.conf\n<\/code><\/pre>\n<p>\u5982\u679c\u6ca1\u6709\u8f93\u51fa\uff0c\u4e5f\u5c31\u662f\u6ca1\u6709\u9519\u8bef\uff0c\u5c31\u53ef\u4ee5\u542f\u7528\u670d\u52a1\u4e86\uff1a<\/p>\n<pre><code class=\"language-bash\"># \u5728 Ubuntu\/Debian \u4e0a\nsudo systemctl enable --now nftables\n<\/code><\/pre>\n<p><strong>\u518d\u6b21\u5f3a\u8c03\uff0c\u4e00\u5b9a\u8981\u5728\u8fd9\u4e9b\u66f4\u6539\u540e\u4fdd\u8bc1\u81ea\u5df1\u8fd8\u80fd\u8fde\u4e0a\u670d\u52a1\u5668\u518d\u5173\u95ed\u73b0\u6709\u7684\u8fde\u63a5\uff01<\/strong><\/p>\n<h2>\u670d\u52a1\u4f7f\u7528\u7684\u6743\u9650<\/h2>\n<p>\u5373\u4f7f\u4f60\u4e3a\u4e86\u65b9\u4fbf\u9009\u62e9\u4f7f\u7528 <code>root<\/code> \u767b\u5f55\uff0c\u76f4\u63a5\u4f7f\u7528 <code>root<\/code> \u6743\u9650\u8dd1\u6240\u6709\u7684\u670d\u52a1\u4e5f\u662f\u4e0d\u660e\u667a\u7684\uff0c\u53ea\u8981\u6709\u4e00\u4e2a\u670d\u52a1\u88ab\u6293\u5230\u4e86\u6d1e\uff0c\u6574\u4e2a VPS \u90fd\u5371\u9669\u4e86\u3002\u6709\u4e00\u4e2a\u7b97\u662f\u7b80\u5355\u7684\u65b9\u5f0f\uff0c\u5c31\u662f\u5bf9\u4e0d\u540c\u7684\u670d\u52a1\u521b\u5efa <code>shell<\/code> \u4e3a <code>nologin<\/code> \u7684\u8d26\u6237\uff0c\u7136\u540e\u542f\u52a8\u65f6\u4f7f\u7528\u5404\u81ea\u7684\u7528\u6237\uff0c\u8fd9\u6837\u7684\u8bdd\u98ce\u9669\u76f8\u5bf9\u5c0f\u4e00\u4e9b\u3002\u5c31\u6bd4\u5982\u7f51\u9875\u670d\u52a1\u5668\u4eec\uff0c<code>nginx<\/code>\u3001<code>Apache<\/code> \u6216\u8005 <code>Caddy<\/code>\uff0c\u90fd\u662f\u53ea\u7528\u9ad8\u6743\u9650\u542f\u52a8\u7236\u8fdb\u7a0b\uff0c\u5904\u7406\u8bf7\u6c42\u90fd\u4f7f\u7528\u4f4e\u6743\u9650\uff08\u6bd4\u5982 <code>www-data<\/code>\uff09\u7684\u5b50\u8fdb\u7a0b\u3002<\/p>\n<p>\u5e76\u4e14\uff0c\u5728 <code>root<\/code> \u4e0b\u6267\u884c\u811a\u672c\u67d0\u79cd\u7a0b\u5ea6\u4e0a\u662f\u628a <code>root<\/code> \u6743\u9650\u5728\u8fd9\u6bb5\u65f6\u95f4\u7ed9\u4e86\u811a\u672c\u4f5c\u8005\uff0c\u6240\u4ee5\u8fd9\u5176\u5b9e\u662f\u9ad8\u5371\u884c\u4e3a\u3002\u5728\u4f60\u6267\u884c\u4efb\u4f55\u547d\u4ee4\u6216\u8005\u811a\u672c\u524d\uff0c\u786e\u4fdd\u4f60\u77e5\u9053\u5b83\u662f\u5e72\u4ec0\u4e48\u7684\uff0c\u5c24\u5176\u662f\u5728 <code>root<\/code> \u6743\u9650\u4e0b\u7684\u65f6\u5019\u3002<\/p>\n<\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-378","post","type-post","status-publish","format-standard","hentry","category-experiences"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/posts\/378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tys.fun\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=378"}],"version-history":[{"count":8,"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/posts\/378\/revisions"}],"predecessor-version":[{"id":391,"href":"https:\/\/www.tys.fun\/index.php?rest_route=\/wp\/v2\/posts\/378\/revisions\/391"}],"wp:attachment":[{"href":"https:\/\/www.tys.fun\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tys.fun\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tys.fun\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}