We will not be providing all of the information about our servers, or how they have been configured.
Our servers are hosted on Hetzner, and run using Ubuntu.
Once you buy a server, the first thing you should do before going into the server, you should generate an ssh-key. Generating an ssh key is kinda straight forward.
# generates an ssh key
C:\Users\myfonttyper>ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key
(C:\Users\myfonttyper/.ssh/id_ed25519): ...
Enter passphrase for key: ... # make sure to note that!
Brute forcing passwords with built-in-tools such as Hydra, is easier than ever. You do not have to be a hacking expert to know how to run simple commands such as;
# brute forcing an ssh server with passwords
C:\Users\myfonttyper>hydra -l root -P passwords.txt -IP- ssh
Now that we are logged in as root, we should create a new user, so we can disable the root user.
root@ubuntu-s2h-g8-1:~$ adduser myfonttyper # create a new user
...
.
root@ubuntu-s2h-g8-1:~$ usermod -aG sudo myfonttyper # add the user to sudo
...
.
root@ubuntu-s2h-g8-1:~$ su - myfonttyper # switch to user
However it would also be very important to disable various settings via the ssh config files. First access the ssh config file using;
myfonttyper@ubuntu-s2h-g8-1:~$ sudo vim /etc/ssh/sshd_config
.
.
...
PermitRootLogin no # no root login!
...
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no # disable password auth
...
# and --- to 'no'.
UsePAM no # PAM login disable
...
:wq
.
.
myfonttyper@ubuntu-s2h-g8-1:~$ sudo systemctl reload ssh # reset the ssh service
This should secure the ssh login more. In case you feel more anxious, you are able to secure the ssh attack-surface by modifying the port, though, this is not really recommended.
UFW (Uncomplicated FireWall) is the easiest way to setup a simple, yet efficient firewall. Firewalls are used, to make sure, which ports are able to get used. Aka, it handles outgoing, and incoming traffic.
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw default deny incoming
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw default allow outgoing
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw allow OpenSSH
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw allow 80
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw allow 443
myfonttyper@ubuntu-s2h-g8-1:~$ sudo ufw enable
CAUTION: Do not enable the firewall, before allowing OpenSSH. If you logout, before allowing OpenSSH, you will NOT be able to log back into the ssh server.
After this, the firewall is setup successful. Though, we are not showing all of our commands, this should give an idea, of how to secure a server with an Uncomplicated Firewall.
Configuring a server is very important. But securing the deployment of a web server is also a very, very important. We do not want it to fail because of misconfiguration. So, how do we deploy our servers anyway?
First of, during development, the usage of the .env file, seems
to be reliable, and "good" enough. Removing the .env file is not
necassary during development, but during production it is a
requirement. There are various providers for securing secrets,
such as:
- HashiCorp Vault
- Doppler
- AWS Secrets
- Infisical
It does not matter what provider you use, however, it is important that
during production, do not use .env file for managing secrets as it is
not a secure way.
We went with Doppler, as it seemed the most simple to setup. Setting it up is actually not that difficult.
myfonttyper@ubuntu-s2h-g8-1:~$ touch doppler.yaml
myfonttyper@ubuntu-s2h-g8-1:~$ vi doppler.yaml
...
setup:
- project: myfonttyper
config: prd
...
However, before being able to run the setup command, we need to login. But thankfully, this is very easy by first installing doppler, and then running the login command.
myfonttyper@ubuntu-s2h-g8-1:~$ sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
myfonttyper@ubuntu-s2h-g8-1:~$ curl -sLf --retry 3 --tlsv1.2 --proto "=https" 'https://packages.doppler.com/public/cli/gpg.DE2A7741A397C129.key' | sudo gpg --dearmor -o /usr/share/keyrings/doppler-archive-keyring.gpg
myfonttyper@ubuntu-s2h-g8-1:~$ echo "deb [signed-by=/usr/share/keyrings/doppler-archive-keyring.gpg] https://packages.doppler.com/public/cli/deb/debian any-version main" | sudo tee /etc/apt/sources.list.d/doppler-cli.list
myfonttyper@ubuntu-s2h-g8-1:~$ sudo apt-get update && sudo apt-get install doppler
myfonttyper@ubuntu-s2h-g8-1:~$ doppler login
...
myfonttyper@ubuntu-s2h-g8-1:~$ doppler setup
...
Now that doppler is setup, we can run every command and include;
doppler run -- ...
Before any command, to include the enviroment variables within the ran command.
However, securing the enviroment variables is easy, though, what about ssl though? Like http:// to https://?
NGINX is a service, with which we can setup our web service. Setting up our reverse proxy, by utilising a simple nginx configuration, is a simple, but also a clean way to host our web service.
An example of an nginx.conf file, that could be considered production ready might look like this;
# + added to add spacing
#
http {
+ server {
+ + listen 80;
+ + server_name ...;
+ + return 301 https://$host$request_uri;
+ }
+ server {
+ + listen 443 ssl;
+ + server_name ...;
+ + ssl_certificate /etc/letsencrypt/live/.../fullchain.pem;
+ + ssl_certificate_key /etc/letsencrypt/live/.../privkey.pem;
+ + location ~ /.well-known/acme-challenge {
+ + + allow all;
+ + + root /var/www/certbot;
+ + }
+ + location / {
+ + + proxy_pass http://...:80;
+ + + proxy_set_header Host $host;
+ + }
+ }
}
This is how nginx.conf file, could look like. And, in order to make it work perfectly, we also need to include, of course, the certifications.
myfonttyper@ubuntu-s2h-g8-1:~$ sudo apt-get install certbot python3-certbot-nginx
myfonttyper@ubuntu-s2h-g8-1:~$ sudo certbot --nginx
...
With that, we should have atleast a somehow, secure server. Hopefully this tutorial gave you more insights on how to configure something production ready, and we will catch you in the next one!