Ever wanted to migrate your 3-tier platform to the Cloud and take advantage of Docker? To get an efficient and secure architecture to start building your project, you will need:
Below is a diagram representing a 3-tier architecture that I use in prod, with example of front / app / DB which can be adapted to your needs.
Docker permit to deploy a packaged application with ease. You can be sure that wherever you deploy Nginx (for example), it will behave the same on every host. Nowadays you can find docker image of all the popular apps, and if missing, you can create your own one in few steps.
To deploy these public docker images, Ansible will gives us all the flexibility to download, customize and run the containers, locally or on remote host.
Ansible tools will be installed on Bastion, because this server will have the access key to all servers. More on Bastion below.
With Docker and Ansible, you can redeploy all your infra, in another Cloud within minutes:
The most important aspect is the segregation with security groups (firewalls) and the presence of bastion, which filtered access.
This host acts as the only SSH access door to all our infra (on all other servers, we block port SSH ports access from the outside). We will activate high security on that host (2FA, pubkey-only access, access monitoring) so we can closely control admin access and outside world attacks.
Below are commands to secure SSH connection on your Bastion. Always keep a console open somewhere in case of a bad config.
Create a user account Greg on the server
sudo useradd -d /home/greg -m greg
Add his public key
mkdir /home/greg/.ssh echo "greg_public_key" >> /home/greg/.ssh/authorized_keys
User greg then Log in remotely via his private key:
ssh greg@zeus_ip -i greg_private_key
Change ssh port default port 22 to 32123
nano /etc/ssh/sshd_config Port: 32123
Allow only pubkey access, and so disable SSH password login (if you don't use 2FA)
nano /etc/ssh/sshd_config PasswordAuthentication no
Restart SSH to apply settings
sudo service ssh restart
From another console, try to connect
ssh greg@zeus_ip -i greg_private_key -p 32123
sudo apt-get install libpam-google-authenticat
Configure SSH to use Google Auth
/etc/pam.d/sshd auth required pam_google_authenticator.so nullok #@include common-auth nano /etc/ssh/sshd_config ChallengeResponseAuthentication yes PasswordAuthentication yes AuthenticationMethods publickey,keyboard-interactive sudo service ssh restart
And setup 2FA for Greg:
ssh greg@zeus_ip -i greg_private_key -p 32123 google-authenticator Option: Time based: yes On phone, Open google authentificator app > option > setup new account > scan qr code Backup in a save place all secret keys and scrash code Then yes to all setup questions asked!
nano /etc/apt/apt.conf.d/50unattended-upgrades dpkg-reconfigure -fnoninteractive unattended-upgrades
Critical components (like the DB) should be segregated and only have minimal access from/to the outside. With security groups we only allow only known flows and components to talk together.
One more step (not represented here) could be to set all outbound to deny by default, and open only specific access to the outside.
Install "uncomplicated firewall" if you don't have any Cloud integrated firewall
sudo apt-get install ufw sudo ufw status sudo ufw delault allow outgoing sudo ufw default deny incoming sudo ufw limit 32123/tcp <-- limit permit to stop consecutive failed SSH connection ;-) sudo ufw allow 80/tcp sudo ufw allow 443/tcp .... sudo ufw delete 22/tcp <-- we don't need SSH on 22 anymore sudo ufw status verbose sudo ufw enable
And try to connect from another console (don't close the first console before all is working fine!)
As bastion is now locked, we control the connections from this point only. It makes then lot of sense to monitor SSH logs. With ELK, you can create a dashboard to differentiate successful and denied accesses. Have a look to this post to setup ELK.
Thank you for reading :-) See you in the next post! Greg