commit
e88745d988
1 changed files with 361 additions and 0 deletions
@ -0,0 +1,361 @@ |
|||||||
|
|
||||||
|
## **What is a Bastion Host?** |
||||||
|
|
||||||
|
A bastion host is a special-purpose computer on a network specifically designed and configured to withstand attacks. There are two common network configurations that include bastion hosts and their placement. |
||||||
|
|
||||||
|
The first requires two firewalls, with bastion hosts sitting between the first "outside world" firewall, and an inside firewall, in a DMZ. Often, smaller networks do not have multiple firewalls, so if only one firewall exists in a network, bastion hosts are commonly placed outside the firewall. |
||||||
|
|
||||||
|
### **Getting Started** |
||||||
|
|
||||||
|
You can use the referral badge below to get started with a $100 credit from Digital Ocean or use this link to [DigitalOcean](https://m.do.co/c/42cf2120197b). |
||||||
|
|
||||||
|
[](https://www.digitalocean.com/?refcode=42cf2120197b&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge) |
||||||
|
|
||||||
|
### **DigitalOcean VPC** |
||||||
|
|
||||||
|
On 7 April, 2020, the VPC service replaced the Private Networking service on DigitalOcean. |
||||||
|
|
||||||
|
> A Virtual Private Cloud (VPC) is a private network interface for collections of DigitalOcean resources. VPC networks provide a more secure connection between resources because the network is inaccessible from the public internet and other VPC networks. Traffic within a VPC network doesn’t count against bandwidth usage. |
||||||
|
|
||||||
|
VPC are available at no additional cost and are enabled by default. They serve the same function as VLANs do. You have two options, you can either manual create a VPC network or if you don't have a VPC network DigitalOcean will create it for you when you build a new VPS. |
||||||
|
|
||||||
|
### **DigitalOcean Cloud Firewalls** |
||||||
|
|
||||||
|
> Cloud Firewalls affect both public and VPC network traffic. Rules specific to either must specify the public or private IP range. |
||||||
|
|
||||||
|
We will be creating two cloud firewall rules, one named public-network and the other named private-network. These will be used as Access Control Lists to help protect our VPC network. |
||||||
|
|
||||||
|
Both the Public-Network and Private-Network cloud firewalls should be added to the bastion-host, while only the Private-Network cloud firewall should be added to all other members of your VPS. |
||||||
|
|
||||||
|
**PUBLIC-NETWORK** |
||||||
|
|
||||||
|
* INBOUND RULES : |
||||||
|
|
||||||
|
**Type** | **Protocol** | **Port Range** | **Sources** |
||||||
|
:--- | :--- | :--- | :--- |
||||||
|
ICMP | ICMP | None | All IPv4, All IPv6 |
||||||
|
SSH | TCP | 22 | All IPv4, All IPv6 |
||||||
|
HTTP | TCP | 80 | All IPv4, All IPv6 |
||||||
|
HTTPS | TCP | 443 | All IPv4, All IPv6 |
||||||
|
CUSTOM | UDP | 51820 | All IPv4, All IPv6 |
||||||
|
|
||||||
|
* OUTBOUND RULES : |
||||||
|
|
||||||
|
**Type** | **Protocol** | **Port Range** | **Sources** |
||||||
|
:--- | :--- | :--- | :--- |
||||||
|
ICMP | ICMP | None | All IPv4, All IPv6 |
||||||
|
All TCP | TCP | All Ports | All IPv4, All IPv6 |
||||||
|
All UDP | UDP | All Ports | All IPv4, All IPv6 |
||||||
|
|
||||||
|
**PRIVATE-NETWORK** |
||||||
|
|
||||||
|
* INBOUND RULES : |
||||||
|
|
||||||
|
**Type** | **Protocol** | **Port Range** | **Sources** |
||||||
|
:--- | :--- | :--- | :--- |
||||||
|
ICMP | ICMP | None | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
||||||
|
All TCP | TCP | All Ports | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
||||||
|
All UDP | UDP | All Ports | 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 |
||||||
|
|
||||||
|
* OUTBOUND RULES : |
||||||
|
|
||||||
|
**Type** | **Protocol** | **Port Range** | **Sources** |
||||||
|
:--- | :--- | :--- | :--- |
||||||
|
ICMP | ICMP | None | All IPv4 |
||||||
|
All TCP | TCP | All Ports | All IPv4 |
||||||
|
All UDP | UDP | All Ports | All IPv4 |
||||||
|
|
||||||
|
I also recommend creating new ssh keys to add to your bastion-host. |
||||||
|
|
||||||
|
```bash |
||||||
|
ssh-keygen -b 4096 -a 1000 -t rsa -f ~/.ssh/id_rsa |
||||||
|
``` |
||||||
|
|
||||||
|
Let's lock down your ssh service. |
||||||
|
|
||||||
|
```bash |
||||||
|
$ sudo mv /etc/ssh/sshd_config /etc/ssh/sshd_config.bak |
||||||
|
|
||||||
|
# Harden SSH Settings |
||||||
|
$ sudo cat <<-EOF > /etc/ssh/sshd_config |
||||||
|
HostKey /etc/ssh/ssh_host_ed25519_key |
||||||
|
HostKey /etc/ssh/ssh_host_rsa_key |
||||||
|
HostKey /etc/ssh/ssh_host_ecdsa_key |
||||||
|
AcceptEnv LANG LC_* |
||||||
|
AllowGroups root sudo |
||||||
|
Banner /etc/issue.net |
||||||
|
ChallengeResponseAuthentication no |
||||||
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr |
||||||
|
ClientAliveCountMax 0 |
||||||
|
ClientAliveInterval 300 |
||||||
|
Compression no |
||||||
|
HostbasedAuthentication no |
||||||
|
IgnoreUserKnownHosts yes |
||||||
|
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 |
||||||
|
LoginGraceTime 20 |
||||||
|
LogLevel VERBOSE |
||||||
|
Macs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256 |
||||||
|
MaxAuthTries 3 |
||||||
|
MaxSessions 3 |
||||||
|
MaxStartups 10:30:60 |
||||||
|
PermitEmptyPasswords no |
||||||
|
PermitRootLogin no |
||||||
|
PubkeyAuthentication yes |
||||||
|
PasswordAuthentication no |
||||||
|
PermitUserEnvironment no |
||||||
|
PrintLastLog yes |
||||||
|
PrintMotd no |
||||||
|
StrictModes yes |
||||||
|
Subsystem sftp internal-sftp |
||||||
|
UseDNS no |
||||||
|
UsePAM yes |
||||||
|
X11Forwarding no |
||||||
|
AllowTcpForwarding yes |
||||||
|
EOF |
||||||
|
``` |
||||||
|
|
||||||
|
Create a new set of ssh host keys. |
||||||
|
|
||||||
|
```bash |
||||||
|
## Update ssh_host keys |
||||||
|
rm /etc/ssh/ssh_host_* |
||||||
|
ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key -N "" |
||||||
|
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N "" |
||||||
|
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" |
||||||
|
|
||||||
|
awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe |
||||||
|
mv /etc/ssh/moduli.safe /etc/ssh/moduli |
||||||
|
``` |
||||||
|
|
||||||
|
We need to edit the netplan for both the bastion-host and the webproxy so that the bastion-host handles all routing. |
||||||
|
|
||||||
|
```bash |
||||||
|
sudo nano /etc/netplan/50-cloud-init.yaml |
||||||
|
``` |
||||||
|
|
||||||
|
You can read more details on editing your netplan on DigitalOcean. |
||||||
|
|
||||||
|
```nano |
||||||
|
network: |
||||||
|
version: 2 |
||||||
|
ethernets: |
||||||
|
eth0: |
||||||
|
addresses: |
||||||
|
- xxx.xxx.xxx.xxx/20 |
||||||
|
- 26xx:xxxx:x:xxx::xx:xxxx/64 |
||||||
|
gateway4: xxx.xxx.xxx.1 |
||||||
|
gateway6: 26xx:xxxx:x:xxx::1 |
||||||
|
match: |
||||||
|
macaddress: ab:ab:ab:ab:ab:ab |
||||||
|
nameservers: |
||||||
|
addresses: |
||||||
|
- 1.1.1.1 |
||||||
|
- 1.0.0.1 |
||||||
|
- 2606:4700:4700::1111 |
||||||
|
- 2606:4700:4700::1001 |
||||||
|
search: [technerdonline.com] |
||||||
|
eth1: |
||||||
|
addresses: |
||||||
|
- 10.128.0.2/20 |
||||||
|
match: |
||||||
|
macaddress: ba:ba:ba:ba:ba:ba |
||||||
|
nameservers: |
||||||
|
addresses: |
||||||
|
- 10.128.0.2 |
||||||
|
search: [local] |
||||||
|
routes: |
||||||
|
- to: 10.128.0.0/20 |
||||||
|
via: 10.128.0.2 |
||||||
|
``` |
||||||
|
|
||||||
|
On the proxy server make the following netplan change. |
||||||
|
|
||||||
|
```nano |
||||||
|
network: |
||||||
|
version: 2 |
||||||
|
ethernets: |
||||||
|
eth0: |
||||||
|
addresses: |
||||||
|
- xxx.xxx.xxx.xxx/20 |
||||||
|
- 26xx:xxxx:x:xxx::xx:xxxx/64 |
||||||
|
#gateway4: xxx.xxx.xxx.1 |
||||||
|
#gateway6: 26xx:xxxx:x:xxx::1 |
||||||
|
match: |
||||||
|
macaddress: ab:ab:ab:ab:ab:ab |
||||||
|
nameservers: |
||||||
|
addresses: |
||||||
|
- 1.1.1.1 |
||||||
|
- 1.0.0.1 |
||||||
|
- 2606:4700:4700::1111 |
||||||
|
- 2606:4700:4700::1001 |
||||||
|
search: [technerdonline.com] |
||||||
|
eth1: |
||||||
|
addresses: |
||||||
|
- 10.128.0.3/20 |
||||||
|
match: |
||||||
|
macaddress: ba:ba:ba:ba:ba:ba |
||||||
|
nameservers: |
||||||
|
addresses: |
||||||
|
- 10.128.0.2 |
||||||
|
search: [local] |
||||||
|
routes: |
||||||
|
- to: 0.0.0.0/0 |
||||||
|
via: 10.128.0.2 |
||||||
|
``` |
||||||
|
|
||||||
|
Apply the netplan changes. |
||||||
|
|
||||||
|
```bash |
||||||
|
sudo netplan apply |
||||||
|
``` |
||||||
|
|
||||||
|
We will need to create a set of IPTABLES rules for both IPv4 and IPv6 but first we need to load some Kernel modules. |
||||||
|
|
||||||
|
|
||||||
|
```bash |
||||||
|
sudo nano /etc/modules-load.d/iptables.conf |
||||||
|
``` |
||||||
|
```nano |
||||||
|
overlay |
||||||
|
br_netfilter |
||||||
|
ip_vs |
||||||
|
ip_vs_rr |
||||||
|
ip_vs_wrr |
||||||
|
ip_vs_sh |
||||||
|
nf_conntrack |
||||||
|
iptable_nat |
||||||
|
iptable_filter |
||||||
|
iptable_mangle |
||||||
|
ip_nf_target_redirect |
||||||
|
ip_set |
||||||
|
ip_vs_nfct |
||||||
|
ip_vs_proto_tcp |
||||||
|
ip_vs_proto_udp |
||||||
|
veth |
||||||
|
bridge |
||||||
|
bridge_netfilter |
||||||
|
ip_nf_filter |
||||||
|
ip_nf_target_masquerade |
||||||
|
netfilter_xt_match_addrtype |
||||||
|
netfilter_xt_match_conntrack |
||||||
|
netfilter_xt_match_ipvs |
||||||
|
nf_nat |
||||||
|
``` |
||||||
|
|
||||||
|
Copy and paste the following content, replacing PUBLIC_IP with the public IP address of the bastion-host, WEBPROXY_PRIVATE_IP with the VPC IP address for the webproxy, and BASTION_PRIVATE_IP with the VPC IP address with the bastion host private IP. |
||||||
|
|
||||||
|
```bash |
||||||
|
nano ipv4.conf |
||||||
|
``` |
||||||
|
|
||||||
|
```nano |
||||||
|
*mangle |
||||||
|
:PREROUTING ACCEPT [0:0] |
||||||
|
:INPUT ACCEPT [0:0] |
||||||
|
:FORWARD ACCEPT [0:0] |
||||||
|
:OUTPUT ACCEPT [0:0] |
||||||
|
:POSTROUTING ACCEPT [0:0] |
||||||
|
COMMIT |
||||||
|
|
||||||
|
*nat |
||||||
|
:PREROUTING ACCEPT [0:0] |
||||||
|
:INPUT ACCEPT [0:0] |
||||||
|
:OUTPUT ACCEPT [0:0] |
||||||
|
:POSTROUTING ACCEPT [0:0] |
||||||
|
-A PREROUTING -i eth0 -d {PUBLIC_IP} -p tcp -m tcp --dport 80 -j DNAT --to-destination {WEBPROXY_PRIVATE_IP}:80 |
||||||
|
-A PREROUTING -i eth0 -d {PUBLIC_IP} -p tcp -m tcp --dport 443 -j DNAT --to-destination {WEBPROXY_PRIVATE_IP}:443 |
||||||
|
-A POSTROUTING -d {WEBPROXY_PRIVATE_IP} -o eth1 -p tcp -m tcp --dport 80 -j SNAT --to-source {BASTION_PRIVATE_IP} |
||||||
|
-A POSTROUTING -d {WEBPROXY_PRIVATE_IP} -o eth1 -p tcp -m tcp --dport 443 -j SNAT --to-source {BASTION_PRIVATE_IP} |
||||||
|
-A POSTROUTING -s {BASTION_PRIVATE_IP} -o eth0 -j SNAT --to-source {PUBLIC_IP} |
||||||
|
-A POSTROUTING -s {PRIVATE_SUBNET} ! -d {PRIVATE_SUBNET} -j MASQUERADE |
||||||
|
COMMIT |
||||||
|
|
||||||
|
*filter |
||||||
|
:INPUT DROP [0:0] |
||||||
|
:FORWARD DROP [0:0] |
||||||
|
:OUTPUT ACCEPT [0:0] |
||||||
|
:FILTERS - [0:0] |
||||||
|
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A INPUT -i lo -j ACCEPT |
||||||
|
-A INPUT -m conntrack --ctstate INVALID -j DROP |
||||||
|
-A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 5/sec -j ACCEPT |
||||||
|
-A INPUT -i eth1 -m conntrack --ctstate NEW -s {PRIVATE_SUBNET} -j ACCEPT |
||||||
|
-A INPUT -j FILTERS |
||||||
|
-A INPUT -j DROP |
||||||
|
-A FORWARD -o eth1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FORWARD -i eth1 -o eth1 -m conntrack --ctstate NEW -s {PRIVATE_SUBNET} -j ACCEPT |
||||||
|
-A FORWARD -o eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate NEW -s {PRIVATE_SUBNET} -j ACCEPT |
||||||
|
-A FORWARD -i eth0 -o eth1 -j FILTERS |
||||||
|
-A OUTPUT -o lo -j ACCEPT |
||||||
|
-A OUTPUT -o eth0 -j ACCEPT |
||||||
|
-A OUTPUT -o eth1 -j ACCEPT |
||||||
|
-A FILTERS -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FILTERS -p tcp -m conntrack --ctstate NEW -m tcp --syn --dport 22 -j ACCEPT |
||||||
|
-A FILTERS -p tcp -m conntrack --ctstate NEW -m tcp --syn --dport 80 -j ACCEPT |
||||||
|
-A FILTERS -p tcp -m conntrack --ctstate NEW -m tcp --syn --dport 443 -j ACCEPT |
||||||
|
-A FILTERS -p udp -m conntrack --ctstate NEW -m udp --dport 51820 -j ACCEPT |
||||||
|
-A FILTERS -p udp -m conntrack --ctstate NEW -m udp --dport 51821 -j ACCEPT |
||||||
|
-A FILTERS -m conntrack --ctstate INVALID -j DROP |
||||||
|
-A FILTERS -j REJECT |
||||||
|
COMMIT |
||||||
|
``` |
||||||
|
|
||||||
|
Now create IPTABLES Rules for IPv6. |
||||||
|
|
||||||
|
```bash |
||||||
|
nano ipv6.conf |
||||||
|
``` |
||||||
|
|
||||||
|
```nano |
||||||
|
*nat |
||||||
|
:PREROUTING ACCEPT [0:0] |
||||||
|
:INPUT ACCEPT [0:0] |
||||||
|
:OUTPUT ACCEPT [0:0] |
||||||
|
:POSTROUTING ACCEPT [0:0] |
||||||
|
COMMIT |
||||||
|
|
||||||
|
*filter |
||||||
|
:INPUT DROP [0:0] |
||||||
|
:FORWARD DROP [0:0] |
||||||
|
:OUTPUT ACCEPT [0:0] |
||||||
|
:FILTERS - [0:0] |
||||||
|
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A INPUT -i lo -j ACCEPT |
||||||
|
-A INPUT -m conntrack --ctstate INVALID -j DROP |
||||||
|
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 128 -m limit --limit 5/sec -j ACCEPT |
||||||
|
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m limit --limit 5/sec -j ACCEPT |
||||||
|
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m limit --limit 5/sec -j ACCEPT |
||||||
|
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m limit --limit 5/sec -j ACCEPT |
||||||
|
-A INPUT -j FILTERS |
||||||
|
-A INPUT -j DROP |
||||||
|
-A FILTERS -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FILTERS -p tcp -m conntrack --ctstate NEW -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT |
||||||
|
-A FILTERS -p tcp -m conntrack --ctstate NEW -m tcp --dport 443 --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT |
||||||
|
-A FILTERS -m conntrack --ctstate INVALID -j DROP |
||||||
|
-A FILTERS -j REJECT |
||||||
|
-A OUTPUT -o lo -j ACCEPT |
||||||
|
-A OUTPUT -o eth0 -j ACCEPT |
||||||
|
-A OUTPUT -o eth1 -j ACCEPT |
||||||
|
-A FORWARD -o eth1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FORWARD -i eth1 -o eth1 -j FILTERS |
||||||
|
-A FORWARD -o eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT |
||||||
|
-A FORWARD -i eth1 -o eth0 -m conntrack --ctstate NEW -j ACCEPT |
||||||
|
-A FORWARD -i eth0 -o eth1 -j FILTERS |
||||||
|
-A FORWARD -j REJECT |
||||||
|
COMMIT |
||||||
|
``` |
||||||
|
|
||||||
|
Apply the iptables rules and install iptables-persistent. |
||||||
|
|
||||||
|
```bash |
||||||
|
sudo iptables-restore -n ipv4.conf |
||||||
|
sudo ip6tables-restore -n ipv6.conf |
||||||
|
|
||||||
|
sudo iptables-save |
||||||
|
sudo ip6tables-save |
||||||
|
|
||||||
|
sudo apt install iptables-persistent |
||||||
|
``` |
||||||
|
|
||||||
|
Simply install your favorite web server on the proxy droplet (i.e. nginx, caddy, haproxy etc). I would also suggest installing wireguard on the bastion host, it is also pretty easy to get a secure wireguard mesh network setup if you have multiple VPC. |
Loading…
Reference in new issue