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