【51CTO.com快译】Nginx是全球发展势头最猛的开源轻量级高性能Web服务器系统。Nginx可在Linux、 Windows、Mac OS和Solaris等操作系统上运行。Nginx继续人气激增,意味着越来越多的Nginx部署环境需要加以保护。
我们在本教程中将介绍几个常见的Nginx服务器安全要点。
要求
- 运行Ubuntu 18.04或Debian 9的服务器
- 你的服务器上已设置了root密码
1.安装Nginx
首先要把Nginx安装到系统上。运行下列命令来安装它:
apt-get install nginx -y
- 1.
一旦Nginx安装完毕,可以用下列命令检查Nginx的状态:
systemctl status nginx
- 1.
你应该会看到下列输出:
?nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2019-03-10 02:43:14 UTC; 4min 40s ago
Docs: man:nginx(8)
Process: 2271 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
Process: 2281 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 2274 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 2285 (nginx)
Tasks: 2 (limit: 1111)
CGroup: /system.slice/nginx.service
??2285 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
??2290 nginx: worker process
Mar 10 02:43:14 ubuntu1804 systemd[1]: Starting A high performance web server and a reverse proxy server...
Mar 10 02:43:14 ubuntu1804 systemd[1]: nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument
Mar 10 02:43:14 ubuntu1804 systemd[1]: Started A high performance web server and a reverse proxy server.
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
2.更新Nginx
你需要更新Nginx Web服务器系统,因为许多性能上的改进、新的功能和安全补丁在不断添加。大多数现代Linux发行版不会在默认软件包列表中随带新版的Nginx。所以你需要通过软件包管理器来更新新版的Nginx。可以用下列命令来更新Nginx Web服务器系统:
apt-get update -y
apt-get install nginx --reinstall -y
- 1.
- 2.
3.防止信息透露
首先需要防止Nginx透露其版本信息。
默认情况下,Nginx在HTTP报头中显示其名称和版本。
你可以用下列命令来检查:
curl -I http://localhost
- 1.
应该会看到下列输出:
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Sat, 09 Mar 2019 15:28:01 GMT
Content-Type: text/html
Content-Length: 10918
Last-Modified: Fri, 01 Feb 2019 16:05:17 GMT
Connection: keep-alive
ETag: "5c546e3d-2aa6"
Accept-Ranges: bytes
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
在上述输出中,应该会看到Nginx和操作系统的版本。
可以编辑/etc/nginx/nginx.conf文件,隐藏这部分信息:
nano /etc/nginx/nginx.conf
- 1.
在http配置部分里面添加server_tokens off这一行:
http {
##
# Basic Settings
##
server_tokens off;
- 1.
- 2.
- 3.
- 4.
- 5.
完成之后保存并关闭文件。然后重启Nginx Web服务器系统使变更生效:
systemctl restart nginx
- 1.
现在再次运行curl命令:
curl -I http://localhost
- 1.
应该会看到下列输出:
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 09 Mar 2019 15:33:31 GMT
Content-Type: text/html
Content-Length: 10918
Last-Modified: Fri, 01 Feb 2019 16:05:17 GMT
Connection: keep-alive
ETag: "5c546e3d-2aa6"
Accept-Ranges: bytes
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
4.限制IP被访问
Nginx随带一个名为ngx_http_access_module的简单模块,允许或拒绝某个特定的IP地址。
如果你想允许从172.16.0.0/16访问Nginx,但拒绝来自其他子网的访问,那么打开/etc/nginx/sites-enabled/default文件:
nano /etc/nginx/sites-enabled/default
- 1.
在server block里面进行下列更改:
server {
listen 80 default_server;
listen [::]:80 default_server;
allow 172.16.0.0/16;
deny all;
- 1.
- 2.
- 3.
- 4.
- 5.
完成后保存并关闭文件。然后重启Nginx使这些变更生效:
systemctl restart nginx
- 1.
现在,试着从192.168.0.102之类的其他IP地址范围来访问Nginx服务器。
下一步,用下列命令检查Nginx日志:
tail -f /var/log/nginx/error.log
- 1.
你应该会在下列输出中看到访问被禁止:
2019/03/09 16:13:01 [error] 11589#11589: *1 access forbidden by rule, client: 192.168.0.102, server: _, request: "GET /test/ HTTP/1.1", host: "172.16.0.122"
- 1.
5.用TLS保护Nginx
传输层安全(TLS)是安全套接层(SSL)的后续技术。它提供更强大更高效的HTTPS,含有更多的改进,比如Forward Secrecy、与现代的OpenSSL密码组以及HSTS。本教程介绍如何在Nginx中启用自签名的SSL证书。如果你想改而使用let's Encrypt证书,不妨参阅:https://www.howtoforge.com/tutorial/nginx-with-letsencrypt-ciphersuite/。
先用下列命令为SSL创建目录:
mkdir /etc/nginx/ssl/
- 1.
接下来,用下列命令创建密钥和证书:
cd /etc/nginx/ssl/
- 1.
先用下列命令创建密钥:
openssl genrsa -aes256 -out nginx.key 1024
- 1.
你会看到下列输出:
Generating RSA private key, 1024 bit long modulus
...++++++
.............................++++++
e is 65537 (0x010001)
Enter pass phrase for nginx.key:
Verifying - Enter pass phrase for nginx.key:
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
接下来用下列命令创建csr:
openssl req -new -key nginx.key -out nginx.csr
- 1.
提供所有信息,如下所示:
Generating RSA private key, 1024 bit long modulus
...++++++
.............................++++++
e is 65537 (0x010001)
Enter pass phrase for nginx.key:
Verifying - Enter pass phrase for nginx.key:
root@ubuntu1804:~# openssl req -new -key nginx.key -out nginx.csr
Enter pass phrase for nginx.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Gujarat
Locality Name (eg, city) []:Junagadh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IT
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:HITESH
Email Address []:admin@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:admin
An optional company name []:IT
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
接下来用下列命令签名证书:
openssl x509 -req -days 365 -in nginx.csr -signkey nginx.key -out nginx.crt
- 1.
你会看到下列输出:
Signature ok
subject=C = IN, ST = Gujarat, L = Junagadh, O = IT, OU = IT, CN = HITESH, emailAddress = admin@example.com
Getting Private key
Enter pass phrase for nginx.key:
- 1.
- 2.
- 3.
- 4.
接下来打开Nginx默认虚拟主机文件,定义证书:
nano /etc/nginx/sites-enabled/default
- 1.
进行下列更改:
server {
listen 192.168.0.100:443 ssl;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
完成后保存并关闭文件。然后重启Nginx服务器使这些变更生效:
systemctl restart nginx
- 1.
6.用密码保护目录
创建Nginx Web服务器时,还可以用密码来保护特定的目录。可以使用.htpasswd文件来做到这一点。
为此用下列命令创建passwd文件,并为它添加用户:
mkdir /etc/nginx/.htpasswd
htpasswd -c /etc/nginx/.htpasswd/passwd admin
- 1.
- 2.
你会看到下列输出:
New password:
Re-type new password:
Adding password for user admin
- 1.
- 2.
- 3.
接下来用下列命令在Nginx Web root里面创建测试目录。
mkdir /var/www/html/test
- 1.
接下来用下列命令为www-data user赋予所有权:
chown -R www-data:www-data /var/www/html/test
- 1.
接下来用下列命令打开Nginx默认虚拟主机文件:
nano /etc/nginx/sites-enabled/default
- 1.
接下来保护测试目录,如下所示:
location /test {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd/passwd;
- 1.
- 2.
- 3.
完成后保存并关闭文件。然后重启Nginx服务使这些变更生效:
systemctl restart nginx
- 1.
接下来打开Web浏览器,输入URL http://your-server-ip/test。系统会提示你输入用户名和密码,访问测试目录,如下所示:
恭喜你!你已成功保护了Ubuntu 18.04服务器上的Nginx服务器系统。但愿本文可保护你放在Nginx Web服务器上的应用程序。想了解更多信息,可以查阅Nginx安全文档(https://docs.nginx.com/nginx/admin-guide/security-controls/)。
原文作者:Hitesh Jethva
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】