* Security ** Switch APT to HTTPS ~sudo sed -i 's/http:/https:/' /etc/apt/sources.list~ Granted, the repository signature provides enough protection; still, no sense in wasting bandwidth and CPU if someone is meddling. ** Tweak root access On OVH's Debian image: - The =root= account has no password. - =PermitRootLogin= defaults to =prohibit-password=: set it to =no=. ** Enable fail2ban ~lastb~ says there's about 4000 login attempts per day; that makes =/var/log/btmp= much bigger than it needs to be. Debian's fail2ban comes with a jail for ~sshd~, so it's just a matter of ~apt install fail2ban~. ** Tweak user accounts =debian= seems mildly popular among bots looking for valid usernames. Ideally I'd just rename the =debian= account, but renaming does not seem to be a very well-defined operation: ~usermod --login $name --move-home --home /home/$name debian~ gets partway there, but leaves a bunch of miscellany to take care of (e.g. sudoers). So instead, I'll - create my own user account: ~sudo adduser $name~ - add it to all groups =debian= belongs to: #+begin_src sh groups=$(groups | sed -e 's/ *debian *//' -e 's/ /,/g') sudo usermod --append --groups ${groups} ${name} #+end_src - only allow password authentication over SSH for this new user account: #+begin_src conf PasswordAuthentication no Match User … PasswordAuthentication yes #+end_src * System #+begin_src sh sudo hostnamectl set-hostname $fqdn sudo timedatectl set-timezone $tz #+end_src * Services ** Web server Run ~sudo apt install nginx~; then, in =/etc/nginx/sites-available/$FQDN=: #+begin_src conf server { listen 80; listen [::]:80; server_name $FQDN www.$FQDN; access_log /var/log/nginx/$FQDN.access.log; root /var/www/$FQDN/html; index index.html; location / { try_files $uri $uri/ =404; } } #+end_src Use one =access_log= file per site, to simplify analytics. Run ~sudo systemctl restart nginx~. *** fail2ban With the following files in =$HOME=: #+begin_src conf # nginx-botsearch.local [Init] block = \S*(php|wp-|wordpress|jenkins|hudson|sql|boaform)[^,]* [Definition] # Change from distro: just remove the leading slash before . failregex = ^ \- \S+ \[\] \"(GET|POST|HEAD) \S+\" 404 .+$ ^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: \, server\: \S*\, request: \"(GET|POST|HEAD) \/ \S+\"\, .*?$ # jail.local [nginx-http-auth] enabled = true [nginx-botsearch] enabled = true # Assume that each requests to $fqdn will be logged to "$fqdn.access.log". logpath = /var/log/nginx/*access.log #+end_src Then: #+begin_src sh sudo cp ~/nginx-botsearch.local /etc/fail2ban/filter.d/ sudo cp ~/jail.local /etc/fail2ban/ sudo systemctl restart fail2ban #+end_src Check how these rules fare against real bot searches with ~fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-botsearch.local~. ** Git server *** SSH access #+begin_src sh $ sudo apt install git $ sudo tee -a /etc/shells <<< $(which git-shell) $ sudo adduser git --disabled-password --shell $(which git-shell) $ sudo mkdir /srv/git $ sudo chown git:git /srv/git # For every new repo: $ sudo -u git git init --bare --shared=group /srv/git/${repo} #+end_src *** Web mirror With =/etc/nginx/sites-available/git.$FQDN=: #+begin_src conf server { listen 80; listen [::]:80; server_name git.$FQQN; access_log /var/log/nginx/git.$FQQN.access.log; root /usr/share/cgit; try_files $uri @cgit; 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; } } #+end_src And =/etc/cgitrc/=: #+begin_src conf css=/cgit.css logo=/cgit.png virtual-root=/ clone-prefix=http://git.$FQDN clone-url=http://git.$FQDN/$CGIT_REPO_URL enable-git-config=1 enable-http-clone=1 enable-index-owner=0 scan-path=/srv/git #+end_src In each repository: - fill in =description=, - fill =[cgit]= section in =config= (=hide=, =owner=, =section=). Do: #+begin_src sh $ sudo apt install cgit fcgiwrap $ ( cd /etc/sites-enabled/ && ln -s ../sites-avaiable/git.$FQDN . ) $ sudo systemctl restart nginx # Make fail2ban notice the new log file. $ sudo systemctl restart fail2ban #+end_src