Overview
This post is aiming to design and implement a secure web service. The server systems are using debian based system.
Network and Service Design
The firewall of cloud server will only expose two ports 80 and 443 which works for http and https web services.
Creating a secure TCP tunnel for connecting all the servers, in one virtual internal network, same IP range. Using Nginx as proxy and web service on all servers.
The cloud server Nginx is used as a layer 7 reverse proxy to local web server or servers to expose web service securely.
Network Setup
Cloud server
Enable firewall on the cloud, based on different provider. Add http and https service to the allow list.
Setup up the secure TCP tunnel. Configure the IP address 172.26.0.9
at /etc/netplan/01-netcfg.yaml
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
Generate ssh key for login with ssh-keygen
Copy key to the server: ssh-copy-id -i .ssh/id_rsa.pub [email protected]
Disable password login with editing /etc/ssh/sshd_config
PasswordAuthentication no
Local server
Setup up the secure TCP tunnel. Configure the IP address 172.26.0.6
same as the cloud.
Testing connection with cloud server.
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 Service Impletement
Setup Cloud server
Install Nginx and edit /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;
}
}
Reload 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
Local Web Service
Install Nginx and edit root path of the default configure file.
Edit /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;
}
}
Add a test index page:
tom@local-server:~# echo "<h1>Testing</h1>" > /var/www/html/index.html
Reload 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
Testing
On local server:
tom@local-server:~# curl localhost
<h1>Testing</h1>
On the cloud:
root@Web:~# curl localhost
<h1>Testing</h1>
Now, open the link, “Testing” should showing on the browser.