概述

这篇文章旨在设计和实现一个安全的 Web 服务。 服务器系统使用基于 Ubuntu/Debian 的系统。

网络和服务设计

公网服务器开启防火墙,仅提供80和443端口,作为 http 和 https 服务访问端口。

使用TCP隧道连接本地服务器和公网服务器,组成一个虚拟内网。

details

因为云服务器性能限制,仅安装Nginx,作为反向代理服务,安全的对外提供本地的web服务。(其实是没有公网IP。(bushi!

服务器网络配置

云服务器

在云供应商后台,开启防火墙,添加80和443端口到白名单。防火墙规则应用到云服务器。

安装,配置TCP隧道,在 /etc/netplan/01-netcfg.yaml 配置内网 IP 地址 172.26.0.9

root@Web:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 56:00:01:50:40:b8 brd ff:ff:ff:ff:ff:ff
    inet 207.246.115.80/23 brd 207.246.115.255 scope global dynamic ens3
       valid_lft 81340sec preferred_lft 81340sec
    inet6 2001:19f0:9002:19e5:5400:1ff:fe50:40b8/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591817sec preferred_lft 604617sec
    inet6 fe80::5400:1ff:fe50:40b8/64 scope link 
       valid_lft forever preferred_lft forever
3: tcp_network: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1200 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 12:fd:c0:ce:22:d2 brd ff:ff:ff:ff:ff:ff
    inet 172.26.0.9/16 brd 172.26.255.255 scope global tcp_network
       valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:bb:ac:2b:4b brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

使用ssh-keygen生成一对ssh密钥。

在云服务器上添加公钥:ssh-copy-id -i .ssh/id_rsa.pub [email protected]

修改ssh配置,禁止使用密码登陆:/etc/ssh/sshd_config

PasswordAuthentication no

本地服务器

同样的安装、配置TCP隧道,及本地IP地址:172.26.0.6

测试本地服务器与云服务器的连通性。

tom@local-server:~# ping 172.26.0.9
PING 172.26.0.9 (172.26.0.9) 56(84) bytes of data.
64 bytes from 172.26.0.9: icmp_seq=1 ttl=64 time=1798 ms
64 bytes from 172.26.0.9: icmp_seq=2 ttl=64 time=728 ms
64 bytes from 172.26.0.9: icmp_seq=3 ttl=64 time=282 ms
64 bytes from 172.26.0.9: icmp_seq=4 ttl=64 time=278 ms
64 bytes from 172.26.0.9: icmp_seq=5 ttl=64 time=278 ms
64 bytes from 172.26.0.9: icmp_seq=6 ttl=64 time=162 ms
64 bytes from 172.26.0.9: icmp_seq=7 ttl=64 time=164 ms
64 bytes from 172.26.0.9: icmp_seq=8 ttl=64 time=163 ms
64 bytes from 172.26.0.9: icmp_seq=9 ttl=64 time=164 ms
^C
--- 172.26.0.9 ping statistics ---
11 packets transmitted, 9 received, 18.1818% packet loss, time 120ms
rtt min/avg/max/mdev = 161.755/446.246/1797.787/506.658 ms, pipe 2

Web/Nginx服务配置

云服务器配置

安装Nginx,修改配置文件 /etc/nginx/sites-enabled/default

server {
  listen 80 default_server;
  listen [::]:80 default_server;

#  root /var/www/html;
#  index index.html index.htm index.nginx-debian.html;
#  server_name _;

  # Update domain;
  server_name  itomhu.com *.itomhu.com;

  # Configure all traffic pass to the web service
  location / {
#    try_files $uri $uri/ =404;
    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;

    # Local web server IP address
    proxy_pass              http://172.26.0.6;
  }
}

重新加载 Nginx:

root@Web:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
root@Web:~# systemctl reload nginx

本地 Web 服务

安装Nginx,修改默认配置文件:/etc/nginx/sites-enabled/default

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  # Update root path or try default
  root /var/www/html;

  index index.html index.htm index.nginx-debian.html;
  server_name _;

  location / {
    try_files $uri $uri/ =404;
  }
}

添加一个测试页面

tom@local-server:~# echo "<h1>测试</h1>" > /var/www/html/index.html

重新加载 Nginx配置:

tom@local-server:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
tom@local-server:~# systemctl reload nginx

测试

本地服务器:

tom@local-server:~# curl localhost
<h1>测试</h1>

云服务器

root@Web:~# curl localhost
<h1>测试</h1>

现在打开域名,一个巨大的测试就会在网页上出现啦~