VPS Setup (website, git, mail)

DNS

Point your A, AAAA records to your server’s ip

HOST TYPE VALUE TTL
* A 192.168.1.1 300
@ A 192.168.1.1 300
git A 192.168.1.1 300
www A 192.168.1.1 300
* AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334 300
@ AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334 300
www AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334 300

Harden your server

Change root password to a more secure one:

passwd
123

Create /root/.ssh/authorized_keys file. Paste your public ssh key there.

Edit /etc/ssh/sshd_config:

Disable password auth and use a non-standard port for ssh

port 12345
PubkeyAuthentication yes
PasswordAuthentication no

Restart sshd service

systemctl restart sshd

Update your server

apt update && apt upgrade

Install needed packages

apt install nginx python3-certbot-nginx rsync ufw

Configure firewall

ufw allow http
ufw allow https
ufw allow 12345/tcp # your ssh port, don't FUCK this up
ufw enable

Configure NGINX

Example code for subdomains e.g. /etc/nginx/sites-available/subdomain

server {
    listen 80 ;
    listen [::]:80 ;

    root /var/www/folder;
    index index.html ;
    server_name subdomain.example.org ;

    location / {
    try_files $uri $uri/ =404;
    }
}

Create nginx config for a static website using example above. This will be our homepage.

server {
    listen 80 ;
    listen [::]:80 ;

    root /var/www/yoursite ;
    index index.html ;
    server_name example.org ;

    location / {
    try_files $uri $uri/ =404;
    }
}

Now you can place your index.html and gorgeous style.css inside /var/www/yoursite

rsync source code of your site

rsync --delete --exclude='.git/' srcdir/ root@example.org:/var/www/yoursite/

Make your site available on the internet

ln -s /etc/nginx/sites-available/yoursite /etc/nginx/sites-enabled/
systemctl reload nginx

Get a certificate for your site

or else glowies will see everything and I mean everything

certbot --nginx

Set up a mail server

Create /etc/nginx/sites-available/mail

server {
    listen 80 ;
    listen [::]:80 ;

    root /var/www/mail;
    index index.html ;
    server_name mail.example.org ;

    location / {
    try_files $uri $uri/ =404;
    }
}
ln -s /etc/nginx/sites-available/mail /etc/nginx/sites-enabled/
systemctl reload nginx

Install dependencies

apt install fail2ban spamc spamd spamassassin python3-systemd

Run a script that will actually do everything for us

curl -LO lukesmith.xyz/emailwiz.sh
sh emailwiz.sh

When prompted choose Internet Site and for system mail name enter “example.org” without subdomain part.

Add more DNS records

HOST TYPE VALUE TTL
mail.example.org CNAME example.org. 300
_dmarc TXT v=DMARC1…(output from emailwiz) 300
example.org TXT v=spf1…(output from emailwiz) 300
mail._domainkey TXT v=DKIM1…(output from emailwiz) 300
example.org MX mail.example.org 10 300

Add users

useradd -G mail,sudo -m USER

fail2ban

Just copy jail.conf to jail.local inside /etc/fail2ban and edit it. Find dovecot and postfix-sasl sections and add

maxretry = 1
bantime = 21600

Set up a git server

Install dependencies

apt install git cgit fcgiwrap highlight python3-markdown

Create git user and paste your public ssh key into authorized_keys

sudo adduser git
su - git
mkdir .ssh && chmod 700 .ssh
touch .ssh/authorized_keys

Create directories and make them available for git

mkdir -p /var/git/repos
chown -R git:git /var/git/repos

Create nginx configuration

server {
	listen 80 ;
	listen [::]:80 ;

	server_name git.example.org;

	root /usr/share/cgit ;
	try_files $uri @cgit ;

	location ~ /.+/(info/refs|git-upload-pack) {
		include             fastcgi_params;
		fastcgi_param       SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
		fastcgi_param       PATH_INFO           $uri;
		fastcgi_param       GIT_HTTP_EXPORT_ALL 1;
		fastcgi_param       GIT_PROJECT_ROOT    /var/git/repos;
		fastcgi_param       HOME                /var/git/repos;
		fastcgi_pass        unix:/run/fcgiwrap.socket;
	}

	location @cgit {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
		fastcgi_param PATH_INFO $uri;
		fastcgi_param QUERY_STRING $args;
		fastcgi_param HTTP_HOST $server_name;
		fastcgi_pass unix:/run/fcgiwrap.socket;
	}

}

Enable it

ln -s /etc/nginx/sites-available/cgit /etc/nginx/sites-enabled/
systemctl reload nginx

Edit /etc/cgitrc

css=/cgit.css
logo=
virtual-root=/
clone-prefix=https://git.example.org

root-title=SOMEONE's git server
root-desc=A web interface to my git repositories, powered by Cgit
head-include=/usr/share/cgit/header.html
footer=/usr/share/cgit/footer.html
source-filter=/usr/lib/cgit/filters/syntax-highlighting.sh
about-filter=/usr/lib/cgit/filters/about-formatting.sh
readme=:README.md

scan-path=/var/git/repos

Optional: rsync your styles into /usr/share/cgit

Troubleshooting

If you get error 500 when clonning your git repo by HTTPS then you need to execute the following command as root

git config --system --add safe.directory '*'

More hardening

Since we created user with sudo group we don’t need and don’t want to log in as root anymore. Edit /etc/ssh/sshd_config

PermitRootLogin no

and restart sshd service

sudo systemctl restart sshd