nginx 配置子域名访问服务器对应端口服务(以及一些问题)

nginx 配置子域名访问服务器对应端口服务

环境:ubuntu 22.04

背景:买了 RackNerd 的 1g 服务器,只能用于 frp 内网穿透了。之前 2g 的还能 docker 跑个 nginx proxy manager,现在只能自己折腾 nginx 了。

一些问题:

  1. 各位佬,下面的 nginx 的配置有什么需要优化补充的不?或者还有哪些实用的 nginx 配置要补充一下?我是根据 GPT 折腾的,但这样倒是也达到我的目的了。坛友倒是有分享了一个配置自动生成的(Digital Ocean),但一堆选项不知道怎么搞。
  2. 如何配置禁止 ip 地址加端口访问,只允许使用域名访问呢?

安装 nginx

  1. sudo apt update

  2. sudo apt install nginx -y ,等到安装完成后访问 ip 地址显示 nginx 欢迎页即成功。

    如果启用了 ufw,则使用 sudo ufw allow 'Nginx Full' 放行 nginx80443 端口。

申请 SSL 证书

  1. 在域名的 DNS 服务商处设置 A 类型解析,如 test.example.com 指向 123.123.123.123(你的服务器 ip)。

  2. 使用 Let’s Encrypt 申请证书,使用命令 sudo apt install certbot python3-certbot-nginx -y 安装 certbot。

  3. 使用命令 sudo certbot --nginx -d test.example.comtest.example.com 申请 SSL 证书,输入邮箱,之后都输入 Y(ES)

    生成的证书在目录:

    /etc/letsencrypt/live/test.example.com/fullchain.pem: 这个文件包含了你的域名的完整证书链,包括你的证书和中间证书。

    /etc/letsencrypt/live/test.example.com/privkey.pem: 这个文件包含了你的域名的私钥,用于加密通信。

    sudo certbot --nginx --certonly -d test.example.com :命令可以只生成证书,而不向 nginx 配置文件中写入配置。

配置 nginx

  1. 创建子域名配置文件:sudo vim /etc/nginx/sites-available/test.example.com

  2. 填入如下配置(test.example.com替换为你的域名,端口替换为你的服务端口):

    server {
        listen 80;
        listen [::]:80;
        server_name test.example.com;
    
        location / {
            proxy_pass http://127.0.0.1:7890;
            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_set_header X-Forwarded-Proto $scheme;
        }
    }
    
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name test.example.com;
    
        ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;
    
        location / {
            proxy_pass http://127.0.0.1:7890;
            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_set_header X-Forwarded-Proto $scheme;
        }
    
  3. 创建链接以启用配置:sudo ln -s /etc/nginx/sites-available/test.example.com /etc/nginx/sites-enabled/

  4. 如果在前面使用 sudo certbot --nginx -d test.example.com 命令,会在 /etc/nginx/sites-available/default 文件中添加一些配置,这些配置会和第 2 步创建的文件中的配置冲突,我目前把 default 文件中新增的配置注释了,certbot 添加的配置类似如下:

    #server {
    
            # SSL configuration
            #
            # listen 443 ssl default_server;
            # listen [::]:443 ssl default_server;
            #
            # Note: You should disable gzip for SSL traffic.
            # See: https://bugs.debian.org/773332
            #
            # Read up on ssl_ciphers to ensure a secure configuration.
            # See: https://bugs.debian.org/765782
            #
            # Self signed certs generated by the ssl-cert package
            # Don't use them in a production server!
            #
            # include snippets/snakeoil.conf;
    
    #       root /var/www/html;
    
            # Add index.php to the list if you are using PHP
    #       index index.html index.htm index.nginx-debian.html;
    #    server_name test.example.com; # managed by Certbot
    
    
    #       location / {
                    # First attempt to serve request as file, then
                    # as directory, then fall back to displaying a 404.
    #               try_files $uri $uri/ =404;
    #       }
    
            # pass PHP scripts to FastCGI server
            #
            #location ~ \.php$ {
            #       include snippets/fastcgi-php.conf;
            #
            #       # With php-fpm (or other unix sockets):
            #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
            #       # With php-cgi (or other tcp sockets):
            #       fastcgi_pass 127.0.0.1:9000;
            #}
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /\.ht {
            #       deny all;
            #}
    
    
    #    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    #    listen 443 ssl; # managed by Certbot
    #    ssl_certificate /etc/letsencrypt/live/test.example.link/fullchain.pem; # managed by Certbot
    #    ssl_certificate_key /etc/letsencrypt/live/test.example.link/privkey.pem; # managed by Certbot
    #    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    #    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
    #}
    #server {
    #    if ($host = test.example.link) {
    #        return 301 https://$host$request_uri;
    #    } # managed by Certbot
    
    
    #       listen 80 ;
    #       listen [::]:80 ;
    #    server_name test.example.link;
    #    return 404; # managed by Certbot
    
    
    #}
    
  5. 检查 nginx 配置:sudo nginx -t,如果没出错则显示 syntax is ok

  6. 应用 nginx 配置:sudo systemctl reload nginxsudo systemctl restart nginx

  7. 访问你的域名,如 test.example.com

补充

http重定向到https

将访问 http://example.com ,即通过 http 协议访问的请求重定向到 https 协议,配置如下(替换上述第二步即可):

server {
    listen 80;
    listen [::]:80;
    server_name test.example.com;

    # Redirect all HTTP requests to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name test.example.com;

    ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:7890;
        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_set_header X-Forwarded-Proto $scheme;
    }
}

禁用 ip 访问

只禁止了 80 端口的默认访问,ip 加其它端口还是能访问对应服务。

  1. /etc/nginx/sites-available 下的 default 文件备份。

  2. 重新创建一个 default 文件,内容如下:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 444;
    }
    

删除 certbot 申请的证书

certbot delete --cert-name your_domain

31 个赞

攻略帖子直接赞

4 个赞

哇 始皇本人

1 个赞
  • 最好挂个空白/错误证书作为443端口的默认服务,减少通过证书关联ip和域名的可能
  • 只允许域名访问就只开放并用nginx监听指定端口,然后在该端口配个默认服务
5 个赞

:+1:t2:

1 个赞

插眼,已经变成了我的部署笔记了

1 个赞

http{ }
下面可以考虑再加点东西,我加的是这些

        server_tokens off; # 隐藏NginX版本号
        autoindex off; # 禁用Autoindex,避免目录浏览

        # 设置timeout,防御DOS攻击。
        client_body_timeout 10;
        client_header_timeout 30;
        keepalive_timeout 30  30;
        send_timeout 10;

        # 设置NginX缓冲区,防止缓冲区溢出攻击
        client_body_buffer_size  16K;
        client_header_buffer_size 1k;
        client_max_body_size 1m;
        large_client_header_buffers 4 8k;
5 个赞

同感,很细节

来自我的装机笔记

# 清空default
echo "" > /etc/nginx/sites-enabled/default
# 自签证书
   sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
       -keyout /etc/ssl/nginx-selfsigned.key \
       -out /etc/ssl/nginx-selfsigned.crt
# 添加nginx配置
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name _;
        ssl_certificate /etc/ssl/nginx-selfsigned.crt;
        ssl_certificate_key /etc/ssl/nginx-selfsigned.key;
        return 404;
    }
5 个赞

很细 感谢佬~

1 个赞

很细

1 个赞

不错

1 个赞

挺好

1 个赞

搜了一下科普,这个是反代理吧,配置好是不是就能不科学访外了?还不用加端口了

1 个赞

好东西 :smiling_face_with_three_hearts:

学到了 就喜欢我这种小白都能看懂的攻略文

只有1g为什么不考虑用debain呢?Ubuntu占用多

借楼再推荐一个简单的,Caddy,几行命令实现相同效果,无需复杂配置,自动配置https

1 个赞

学到了,还可以这样减少ip关联到域名

感谢分享

实在小白可以用NGINXConfig | DigitalOcean